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

Fonctionnement de FOR XML PATH('') lors de la concaténation de lignes

Qu'est-ce que FOR XML PATH('xxx') fait est de créer une chaîne XML pour le jeu de résultats qui place chaque ligne dans un <xxx></xxx> élément et chaque valeur de colonne à l'intérieur de la ligne, dans un élément portant le nom de cette colonne.

Si le PATH est vide (c'est-à-dire PATH('') ) il omet l'élément de ligne dans la génération XML. Si la colonne n'a pas de nom, elle omet l'élément de colonne dans la génération XML. Lorsque PATH est vide et que les colonnes n'ont pas de nom, cela devient effectivement une concaténation de chaînes de toutes les lignes.

Exécutez les instructions suivantes pour mieux comprendre le processus :

-- Each row is in a <beta></beta> element
-- Each column in that row in a <alfa></alfa> element (the column name)
SELECT
    alfa=','+TABLE_SCHEMA + '.' + TABLE_NAME
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('beta');

-- Since the PATH is empty, the rows are not put inside an element
-- Each column in that row is in a <alfa></alfa> element (the column name)
SELECT
    alfa=','+TABLE_SCHEMA + '.' + TABLE_NAME
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('');

-- Since the PATH is empty, the rows are not put inside an element
-- Since the column has no name it is not put inside an element     
SELECT
    ','+TABLE_SCHEMA + '.' + TABLE_NAME
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('');

-- This uses the STUFF function to remove the leading comma to get a proper comma-seperated list    
SELECT STUFF((
    SELECT
        ','+TABLE_SCHEMA + '.' + TABLE_NAME
    FROM
        INFORMATION_SCHEMA.TABLES
    FOR
        XML PATH('')
    ),1,1,''
) AS comma_seperated_list;

Maintenant, je vous entends demander :comment puis-je supprimer le nom de la colonne lorsque je sélectionne simplement une colonne dans une table. Il existe plusieurs façons, dans l'ordre de mes préférences :

  • Propriétés XQuery :SELECT [text()]=column_name ...
  • Utilisez une sous-requête pour sélectionner la valeur de la colonne :SELECT (SELECT column_name) ...
  • CAST la colonne vers son type :SELECT CAST(column_value AS <TYPE of the column>) ...

Exemples :

SELECT
    [text()]=TABLE_NAME
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('');

SELECT
    (SELECT TABLE_NAME)
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('');

SELECT
    CAST(TABLE_NAME AS SYSNAME)
FROM
    INFORMATION_SCHEMA.TABLES
FOR
    XML PATH('');