Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Conversione di una tabella a 1 riga in una tabella di coppia chiave-valore

Una versione in cui non è coinvolta alcuna dinamica. Se disponi di nomi di colonna non validi da utilizzare come nomi di elementi in XML, l'operazione avrà esito negativo.

select T2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       T2.N.value('text()[1]', 'nvarchar(max)') as Value
from (select *
      from TableA
      for xml path(''), type) as T1(X)
  cross apply T1.X.nodes('/*') as T2(N)

Un campione funzionante:

declare @T table
(
  Column1 varchar(10), 
  Column2 varchar(10), 
  Column3 varchar(10)
)

insert into @T values('V1','V2','V3')

select T2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       T2.N.value('text()[1]', 'nvarchar(max)') as Value
from (select *
      from @T
      for xml path(''), type) as T1(X)
  cross apply T1.X.nodes('/*') as T2(N)

Risultato:

Key                  Value
-------------------- -----
Column1              V1
Column2              V2
Column3              V3

Aggiorna

Per una query con più di una tabella puoi usare for xml auto per ottenere i nomi delle tabelle nell'XML. Nota, se usi l'alias per i nomi delle tabelle nella query otterrai invece l'alias.

select X2.N.value('local-name(..)', 'nvarchar(128)') as TableName,
       X2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       X2.N.value('text()[1]', 'nvarchar(max)') as Value
from (
     -- Your query starts here
     select T1.T1ID,
            T1.T1Col,
            T2.T2ID,
            T2.T2Col
     from T1
       inner join T2
         on T1.T1ID = T2.T1ID
     -- Your query ends here
     for xml auto, elements, type     
     ) as X1(X)
  cross apply X1.X.nodes('//*[text()]') as X2(N)

SQL Fiddle