Я использую этот замечательный пример /dba//a/25818/113298 от Bluefeet, чтобы создать сводную диаграмму и преобразовать ее в данные XML.
Объявление параметра
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);
Далее идет CTE с большим количеством кода, конечный результат CTE помещается во временную DB (так же, как в примере)
SELECT
B.[StayDate] -- this is a date dd-mm-yyyy
, B.[Guid]
INTO #tempDates
FROM BaseSelection B
Генерация столбцов (так же, как в примере)
SELECT @cols = STUFF((SELECT distinct ',' +QUOTENAME(convert(char(10), [StayDate] , 120))
FROM #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
Набор результатов - это то, что я должен был ожидать
set @query =
'SELECT [Guid],' + @cols +'
FROM
(
SELECT
[StayDate]
,[Guid]
FROM #tempDates
) A
pivot
(
count([StayDate])
for [StayDate] in (' + @cols +')
) p
'
EXEC sp_executesql @query ;
Когда я пытаюсь преобразовать его в XML, мои атрибуты конвертируются только частично
set @query =
'SELECT [Guid],' + @cols +'
FROM
(
SELECT
[StayDate]
,[Guid]
FROM #tempDates
) A
pivot
(
count([StayDate])
for [StayDate] in (' + @cols +')
) p
for xml auto
-- when using for XML path i will get a error
-- FOR XML PATH(''''), ROOT(''root'')
-- Msg 6850, Level 16, State 1, Line 3
-- Column name '2016-12-17' contains an invalid XML identifier
-- as required by FOR XML; '2'(0x0032) is the first character at fault.
'
EXEC sp_executesql @query ;
ResultSet
<p Guid="3C3359E3-CFE5-E511-80CA-005056A90901"
_x0032_016-12-17="2" --> should be 2016-12-17="2"
_x0032_016-12-18="2" --> should be 2016-12-18="2"
_x0032_016-12-19="2" --> should be 2016-12-19="2"
/>
Я что-то пропустил, почему только часть даты конвертируется в юникод?
Как я могу это исправить?
sql-server
xml
pivot
Bunkerbuster
источник
источник
Ответы:
Имена атрибутов в XML не могут начинаться с цифры, см. NameStartChar .
Вы должны придумать альтернативные имена для ваших атрибутов и закодировать их в отдельной
@cols
переменной, указав псевдонимы столбцов для вашего динамического сводного запроса.Результат;
Когда вы используете
for xml auto
SQL Server, это делает для вас.источник
Первый персонаж не является Unicode, как таковой. Я имею в виду, что технически все символы в XML в SQL Server кодируются как UTF-16 Little Endian, так что в этом смысле все они являются Unicode. Но то, что вы видите, это просто экранированная нотация для символа, в данном случае «2», которая имеет шестнадцатеричное / двоичное значение «32».
Проблема в том, что имена XML не могут начинаться с цифры. Следующие тесты показывают, что имя атрибута или имя элемента, начинающееся с числа, получает ошибку, но начинать с подчеркивания (
_
) или буквы просто отлично.Таким образом, вам необходимо добавить префикс имени столбца к символу, который является допустимым в качестве начального символа для атрибута XML или имени элемента.
Кроме того, вы уверены, что он "работает" с
FOR XML AUTO
? Из того, что я вижу, это просто автоматическое преобразование «недопустимого» символа в_x0032_
:Возвращает:
источник