Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Aplatissement d'un tableau à 1 ligne dans un tableau de paires clé-valeur

Une version où il n'y a pas de dynamique impliquée. Si vous avez des noms de colonnes qui ne peuvent pas être utilisés comme noms d'éléments dans XML, cela échouera.

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 exemple de travail :

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)

Résultat :

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

Mettre à jour

Pour une requête avec plus d'une table, vous pouvez utiliser for xml auto pour obtenir les noms de table dans le XML. Notez que si vous utilisez un alias pour les noms de table dans la requête, vous obtiendrez l'alias à la place.

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