Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como FOR XML PATH('') funciona ao concatenar linhas


O que FOR XML PATH('xxx') faz é criar uma string XML para o conjunto de resultados que coloca cada linha em um <xxx></xxx> elemento e cada valor de coluna dentro da linha, em um elemento com o nome dessa coluna.

Se o PATH estiver vazio (ou seja, PATH('') ) ele omite o elemento row na geração XML. Se a coluna não tiver nome, omitirá o elemento da coluna na geração do XML. Quando ambos PATH estão vazios e as colunas não têm nomes, ele efetivamente se torna uma concatenação de strings de todas as linhas.

Execute as seguintes instruções para obter uma visão melhor do processo:
-- 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;

Agora eu ouço você perguntando:Como posso remover o nome da coluna quando simplesmente seleciono uma coluna de uma tabela. Existem várias maneiras, em ordem de minha preferência:
  • Propriedades XQuery:SELECT [text()]=column_name ...
  • Use uma subconsulta para selecionar o valor da coluna:SELECT (SELECT column_name) ...
  • CAST a coluna para seu tipo:SELECT CAST(column_value AS <TYPE of the column>) ...

Exemplos:
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('');