Estou usando este ótimo exemplo /dba//a/25818/113298 da Bluefeet, para criar um pivô e transformá-lo em dados xml.
Declarando o parâmetro
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);
Em seguida, há um CTE com muito código, o resultado final do CTE é colocado em um banco de dados temporário (o mesmo que no exemplo)
SELECT
B.[StayDate] -- this is a date dd-mm-yyyy
, B.[Guid]
INTO #tempDates
FROM BaseSelection B
Gerando as colunas (igual ao exemplo)
SELECT @cols = STUFF((SELECT distinct ',' +QUOTENAME(convert(char(10), [StayDate] , 120))
FROM #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
O conjunto de resultados é o que eu deveria esperar
set @query =
'SELECT [Guid],' + @cols +'
FROM
(
SELECT
[StayDate]
,[Guid]
FROM #tempDates
) A
pivot
(
count([StayDate])
for [StayDate] in (' + @cols +')
) p
'
EXEC sp_executesql @query ;
Quando tento transformá-lo em XML, meus atributos são convertidos apenas parcialmente
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 ;
conjunto de resultados
<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"
/>
Perdi alguma coisa, por que apenas uma parte da data é convertida em unicode?
Como posso consertar isso?
sql-server
xml
pivot
Bunkerbuster
fonte
fonte
Respostas:
Os nomes de atributo em XML não podem começar com um número, consulte NameStartChar .
Você precisa criar nomes alternativos para seus atributos e codificá-los em uma
@cols
variável separada especificando aliases de coluna para sua consulta dinâmica dinâmica.Resultado;
Quando você está usando o
for xml auto
SQL Server, faz isso por você.fonte
O primeiro caractere não é Unicode, por si só. Quero dizer, tecnicamente todos os caracteres em XML no SQL Server são codificados como UTF-16 Little Endian, portanto, nesse sentido, eles são todos Unicode. Mas o que você está vendo é apenas a notação de escape de um personagem, neste caso "2", que tem um valor hexadecimal / binário de "32".
O problema é simplesmente que os nomes XML não podem começar com um número. Os testes a seguir mostram que um nome de atributo ou elemento começando com um número recebe um erro, mas começar com um sublinhado (
_
) ou uma letra é bom.Portanto, você precisa prefixar os nomes das colunas com um caractere válido como caractere inicial para um atributo XML ou nome do elemento.
Além disso, você tem certeza de que está "trabalhando"
FOR XML AUTO
? Pelo que posso ver, é simplesmente a conversão automática do caractere "inválido" para_x0032_
:Devoluções:
fonte