Szukaj…


Uwagi

Istnieje również kilka innych trybów FOR XML :

  • FOR XML RAW - Tworzy jeden element <row> na wiersz.
  • FOR XML AUTO - Próby heurystycznego automatycznego generowania hierarchii.
  • FOR XML EXPLICIT - Zapewnia większą kontrolę nad kształtem XML, ale jest bardziej kłopotliwy niż FOR XML PATH .

Hello World XML

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

Określanie przestrzeni nazw

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>

Określanie struktury za pomocą wyrażeń 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>

W FOR XML PATH kolumny bez nazwy stają się węzłami tekstowymi. NULL lub '' stają się zatem pustymi węzłami tekstowymi. Uwaga: możesz przekonwertować nazwaną kolumnę na nienazwaną, używając 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>

Korzystanie z (pustych) węzłów tekstowych pomaga oddzielić poprzedni węzeł wyjściowy od następnego, dzięki czemu SQL Server wie, jak rozpocząć nowy element dla następnej kolumny. W przeciwnym razie zostanie zdezorientowany, gdy atrybut już istnieje w tym, co uważa za element „bieżący”.

Na przykład bez pustych ciągów między elementem a atrybutem w instrukcji SELECT SQL Server podaje błąd:

Kolumna zorientowana na atrybuty „FLD / @ NAME” nie może występować po nie-zorientowanym na atrybuty rodzeństwie w hierarchii XML w FOR XML PATH.

Należy również zauważyć, że ten przykład również zawinął XML w element główny o nazwie row , określony przez ROOT('row')

Używanie FOR XML PATH do łączenia wartości

FOR XML PATH może być używana do łączenia wartości w łańcuch. Poniższy przykład łączy wartości w łańcuch 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
    ,''
);

Kilka ważnych uwag:

  • klauzula ORDER BY może być użyta do uporządkowania wartości w preferowany sposób
  • jeśli jako separator konkatenacji zostanie użyta dłuższa wartość, parametr funkcji STUFF musi zostać zmieniony;
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
    ,''
);
  • ponieważ używana jest opcja TYPE i funkcja .value , konkatenacja działa z NVARCHAR(MAX)


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow