Korzystam z tego wspaniałego przykładu /dba//a/25818/113298 z Bluefeet, aby utworzyć oś przestawną i przekształcić ją w dane XML.
Deklaracja parametru
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);
Następnie jest CTE z dużą ilością kodu, wynik CTE jest umieszczany w temp DB (tak samo jak w przykładzie)
SELECT
B.[StayDate] -- this is a date dd-mm-yyyy
, B.[Guid]
INTO #tempDates
FROM BaseSelection B
Generowanie cols (tak jak w przykładzie)
SELECT @cols = STUFF((SELECT distinct ',' +QUOTENAME(convert(char(10), [StayDate] , 120))
FROM #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
Zestaw wyników jest tym, czego powinienem się spodziewać
set @query =
'SELECT [Guid],' + @cols +'
FROM
(
SELECT
[StayDate]
,[Guid]
FROM #tempDates
) A
pivot
(
count([StayDate])
for [StayDate] in (' + @cols +')
) p
'
EXEC sp_executesql @query ;
Kiedy próbuję przekształcić go w XML, moje atrybuty są tylko częściowo konwertowane
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 ;
zestaw wyników
<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"
/>
Czy coś przeoczyłem, dlaczego tylko część daty jest konwertowana na Unicode?
Jak mogę to naprawić?
sql-server
xml
pivot
Bunkier
źródło
źródło
Odpowiedzi:
Nazwy atrybutów w XML nie mogą zaczynać się od liczby, patrz NameStartChar .
Musisz wymyślić alternatywne nazwy dla swoich atrybutów i zakodować je w osobnej
@cols
zmiennej określającej aliasy kolumn dla dynamicznego zapytania przestawnego.Wynik;
Gdy używasz
for xml auto
SQL Server, robi to za Ciebie.źródło
Pierwszym znakiem nie jest sam w sobie Unicode. Mam na myśli, że technicznie wszystkie znaki w XML w SQL Server są zakodowane jako UTF-16 Little Endian, więc w tym sensie wszystkie są Unicode. Ale to, co widzisz, to tylko znak ucieczki dla znaku, w tym przypadku „2”, który ma wartość szesnastkową / binarną „32”.
Problem polega po prostu na tym, że nazwy XML nie mogą zaczynać się od cyfry. Poniższe testy pokazują, że nazwa atrybutu lub nazwa elementu zaczynająca się od liczby otrzymuje błąd, ale rozpoczęcie od znaku podkreślenia (
_
) lub litery jest w porządku.Musisz więc poprzedzić nazwy kolumn znakiem, który jest poprawny jako znak początkowy dla atrybutu XML lub nazwy elementu.
Czy jesteś pewien, że „współpracuje”
FOR XML AUTO
? Z tego, co widzę, jest to po prostu automatyczna konwersja „nieprawidłowego” znaku na_x0032_
:Zwroty:
źródło