Поиск…


замечания

Существует также несколько других режимов FOR XML :

  • FOR XML RAW - Создает один элемент <row> каждой строки.
  • FOR XML AUTO - попытка эвристического автогенерации иерархии.
  • FOR XML EXPLICIT - обеспечивает больший контроль над формой XML, но является более громоздким, чем FOR XML PATH .

Hello World XML

SELECT 'Hello World' FOR XML PATH('example')
<example>Hello World</example>

Указание пространств имен

SQL Server 2008
WITH XMLNAMESPACES (
    DEFAULT 'http://www.w3.org/2000/svg',
    'http://www.w3.org/1999/xlink' AS xlink
)
SELECT 
    'example.jpg' AS 'image/@xlink:href',
    '50px' AS 'image/@width',
    '50px' AS 'image/@height'
FOR XML PATH('svg')
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
    <image xlink:href="firefox.jpg" width="50px" height="50px"/>
</svg>

Определение структуры с использованием выражений XPath

SELECT
    'XPath example' AS 'head/title',
    'This example demonstrates ' AS 'body/p',
    'https://www.w3.org/TR/xpath/' AS 'body/p/a/@href',
    'XPath expressions' AS 'body/p/a'
FOR XML PATH('html')
<html>
    <head>
        <title>XPath example</title>
    </head>
    <body>
        <p>This example demonstrates <a href="https://www.w3.org/TR/xpath/">XPath expressions</a></p>
    </body>
</html>

В FOR XML PATH столбцы без имени становятся текстовыми узлами. NULL или '' поэтому становятся пустыми текстовыми узлами. Примечание. Вы можете преобразовать именованный столбец в неназванный, используя AS *

DECLARE @tempTable TABLE (Ref INT, Des NVARCHAR(100), Qty INT)
INSERT INTO @tempTable VALUES (100001, 'Normal', 1), (100002, 'Foobar', 1), (100003, 'Hello World', 2)

SELECT ROW_NUMBER() OVER (ORDER BY Ref) AS '@NUM',
     'REF' AS 'FLD/@NAME', REF AS 'FLD', '',
     'DES' AS 'FLD/@NAME', DES AS 'FLD', '',
     'QTY' AS 'FLD/@NAME', QTY AS 'FLD'
FROM @tempTable 
FOR XML PATH('LIN'), ROOT('row')
<row>
  <LIN NUM="1">
    <FLD NAME="REF">100001</FLD>
    <FLD NAME="DES">Normal</FLD>
    <FLD NAME="QTY">1</FLD>
  </LIN>
  <LIN NUM="2">
    <FLD NAME="REF">100002</FLD>
    <FLD NAME="DES">Foobar</FLD>
    <FLD NAME="QTY">1</FLD>
  </LIN>
  <LIN NUM="3">
    <FLD NAME="REF">100003</FLD>
    <FLD NAME="DES">Hello World</FLD>
    <FLD NAME="QTY">2</FLD>
  </LIN>
</row>

Использование (пустых) текстовых узлов помогает отделить предыдущий выходной узел от следующего, так что SQL Server знает, как запустить новый элемент для следующего столбца. В противном случае он запутывается, когда атрибут уже существует в том, что он считает «текущим» элементом.

Например, без пустых строк между элементом и атрибутом в SELECT SQL Server дает ошибку:

Столбец с атрибутом «FLD / @ NAME» не должен появляться после не-атрибут-центричного брата в иерархии XML в FOR XML PATH.

Также обратите внимание, что этот пример также обернул XML в корневой элемент с именем row , указанный ROOT('row')

Использование FOR XML PATH для конкатенации значений

FOR XML PATH можно использовать для конкатенации значений в строку. Следующий пример объединяет значения в строку CSV :

DECLARE @DataSource TABLE
(
    [rowID] TINYINT
   ,[FirstName] NVARCHAR(32)
);

INSERT INTO @DataSource ([rowID], [FirstName])
VALUES (1, 'Alex')
      ,(2, 'Peter')
      ,(3, 'Alexsandyr')
      ,(4, 'George');

SELECT STUFF
(
    (
        SELECT ',' + [FirstName]
        FROM @DataSource
        ORDER BY [rowID] DESC
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')
    ,1
    ,1
    ,''
);

Несколько важных замечаний:

  • предложение ORDER BY может использоваться для упорядочения значений в предпочтительном порядке
  • если в качестве разделителя конкатенации используется более длинное значение, необходимо также изменить параметр функции STUFF ;
SELECT STUFF
(
    (
        SELECT '---' + [FirstName]
        FROM @DataSource
        ORDER BY [rowID] DESC
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')
    ,1
    ,3 -- the "3" could also be represented as: LEN('---') for clarity
    ,''
);
  • поскольку используются опция TYPE и .value , конкатенация работает с NVARCHAR(MAX)


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow