Sdílet prostřednictvím


Příklady: Použití režimu PATH

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL databáze v Microsoft Fabric

Následující příklady ilustrují použití režimu PATH při generování XML z dotazu SELECT. Mnoho z těchto dotazů je určeno pro dokumenty XML pokynů pro výrobu jízdních kol, které jsou uloženy ve sloupci Pokyny tabulky ProductModel.

Zadání dotazu režimu PATH

Tento dotaz určuje režim FOR XML PATH.

USE AdventureWorks2022;
GO
SELECT
       ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML PATH;
GO

Následující výsledek je XML orientovaný na element, kde každá hodnota sloupce ve výsledné sadě řádků je zabalena do elementu. SELECT Vzhledem k tomu, že klauzule neurčí žádné aliasy pro názvy sloupců, jsou názvy podřízených elementů vygenerované stejné jako odpovídající názvy sloupců v SELECT klauzuli. Ke každému řádku v sadě řádků je přidána značka <row>.

<row>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</row>
<row>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</row>

Následující výsledek je stejný jako RAW dotaz režimu se zadanou ELEMENTS možností. Vrátí xml orientovaný na element s výchozím <row> elementem pro každý řádek v sadě výsledků.

USE AdventureWorks2022;
GO
SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML RAW, ELEMENTS;

Volitelně můžete zadat název prvku řádku, který přepíše výchozí <row>. Například následující dotaz vrátí <ProductModel> prvek pro každý řádek v sadě řádků.

USE AdventureWorks2022;
GO
SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModel');
GO

Výsledný kód XML bude mít zadaný název elementu řádku.

<ProductModel>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</ProductModel>
<ProductModel>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</ProductModel>

Pokud zadáte řetězec nulové délky, obklopující element nebude vytvořen.

USE AdventureWorks2022;
GO
SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML PATH ('');
GO

Toto je výsledek:

<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>

Zadejte názvy sloupců ve stylu XPath

V následujícím dotazu ProductModelID název sloupce začíná znakem @a neobsahuje značku lomítka (/). Proto se ve výsledném XML vytvoří atribut elementu <row> , který má odpovídající hodnotu sloupce.

USE AdventureWorks2022;
GO
SELECT ProductModelID AS "@id",
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML PATH ('ProductModelData');
GO

Toto je výsledek:

<ProductModelData id="122">
  <Name>All-Purpose Bike Stand</Name>
</ProductModelData>
<ProductModelData id="119">
  <Name>Bike Wash</Name>
</ProductModelData>

Můžete přidat jeden prvek nejvyšší úrovně zadáním root možnosti v FOR XML.

SELECT ProductModelID AS "@id",
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModelData'), root ('Root');
GO

Pokud chcete vygenerovat hierarchii, můžete zahrnout syntaxi podobné cestě. Změňte například název Name sloupce na SomeChild/ModelName a získáte XML s hierarchií, jak je znázorněno v tomto výsledku:

<Root>
  <ProductModelData id="122">
    <SomeChild>
      <ModelName>All-Purpose Bike Stand</ModelName>
    </SomeChild>
  </ProductModelData>
  <ProductModelData id="119">
    <SomeChild>
      <ModelName>Bike Wash</ModelName>
    </SomeChild>
  </ProductModelData>
</Root>

Kromě ID a názvu modelu produktu dotaz, který následuje, načte lokality výrobních instrukcí pro model produktu. Vzhledem k tomu, že sloupec Instructions je typu xml, metoda query() datového typu xml je specifikována pro načtení umístění.

SELECT ProductModelID AS "@id",
       Name,
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
                /MI:root/MI:Location
              ') AS ManuInstr
FROM Production.ProductModel
WHERE ProductModelID = 7
FOR XML PATH ('ProductModelData'), root ('Root');
GO

Jedná se o částečný výsledek. Protože dotaz určuje ManuInstr jako název sloupce, XML vrácený query() metodou <ManuInstr> je zabalen do značky, jak je znázorněno v následujícím příkladu:

<Root>
  <ProductModelData id="7">
    <Name>HL Touring Frame</Name>
    <ManuInstr>
      <MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
        <MI:step>...</MI:step>...
      </MI:Location>
      ...
    </ManuInstr>
  </ProductModelData>
</Root>

V předchozím dotazu FOR XML můžete chtít zahrnout jmenné prostory pro prvky <Root> a <ProductModelData>. Můžete to provést tak, že nejprve definujete předponu vazby oboru názvů pomocí FUNKCE XMLNAMESPACES a použijete předpony v dotazu FOR XML. Další informace naleznete v tématu Přidání oborů názvů do dotazů pomocí WITH XMLNAMESPACES.

USE AdventureWorks2022;
GO
WITH XMLNAMESPACES (
   'uri1' AS ns1,
   'uri2' AS ns2,
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' as MI)
SELECT ProductModelID AS "ns1:ProductModelID",
       Name           AS "ns1:Name",
       Instructions.query('
                /MI:root/MI:Location
              ')
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH ('ns2:ProductInfo'), root('ns1:root');
GO

Předpona MI je také definována v objektu WITH XMLNAMESPACES. V důsledku toho query() metoda zadaného typu XML nedefinuje předponu v prologu dotazu. Toto je výsledek:

<ns1:root xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">
  <ns2:ProductInfo>
    <ns1:ProductModelID>7</ns1:ProductModelID>
    <ns1:Name>HL Touring Frame</ns1:Name>
    <MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" LaborHours="2.5" LotSize="100" MachineHours="3" SetupHours="0.5" LocationID="10" xmlns="">
    <MI:step>
      Insert <MI:material>aluminum sheet MS-2341</MI:material> into the <MI:tool>T-85A framing tool</MI:tool>.
    </MI:step>
    ...
    </MI:Location>
    ...
  </ns2:ProductInfo>
</ns1:root>

Generování seznamu hodnot pomocí režimu PATH

Pro každý model produktu tento dotaz vytvoří seznam hodnot ID produktů. Pro každé ID produktu dotaz také vytvoří vnořené elementy <ProductName> , jak je znázorněno v tomto fragmentu XML:

<ProductModelData ProductModelID="7" ProductModelName="..." ProductIDs="product id list in the product model">
  <ProductName>...</ProductName>
  <ProductName>...</ProductName>
  ...
</ProductModelData>

Toto je dotaz, který vytvoří požadovaný kód XML:

USE AdventureWorks2022;
GO
SELECT ProductModelID     AS "@ProductModelID",
       Name               AS "@ProductModelName",
      (SELECT ProductID AS "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')) AS "@ProductIDs",
       (SELECT Name AS "ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
        FOR XML PATH ('')) AS "ProductNames"
FROM   Production.ProductModel
WHERE  ProductModelID= 7 or ProductModelID=9
FOR XML PATH('ProductModelData');

Všimněte si následujících věcí z předchozího dotazu:

  • První vnořená SELECT vrátí seznam ID produktů použitím data() jako název sloupce. Protože dotaz určuje prázdný řetězec jako název prvku řádku v FOR XML PATH, není generován žádný prvek. Místo toho je seznam hodnot přiřazen atributu ProductID .

  • Druhý vnořený SELECT načte názvy produktů v modelu produktu. Generuje prvky, které jsou vráceny <ProductName> zabalené v elementu <ProductNames> , protože dotaz určuje ProductNames jako název sloupce.

Toto je částečný výsledek:

<ProductModelData PId="7" ProductModelName="HL Touring Frame" ProductIDs="885 887 ...">
  <ProductNames>
    <ProductName>HL Touring Frame - Yellow, 60</ProductName>
    <ProductName>HL Touring Frame - Yellow, 46</ProductName>
  </ProductNames>
  ...
</ProductModelData>
<ProductModelData PId="9" ProductModelName="LL Road Frame" ProductIDs="722 723 724 ...">
  <ProductNames>
    <ProductName>LL Road Frame - Black, 58</ProductName>
    <ProductName>LL Road Frame - Black, 60</ProductName>
    <ProductName>LL Road Frame - Black, 62</ProductName>
    ...
  </ProductNames>
</ProductModelData>

Poddotaz, který vytváří názvy produktů, vrátí výsledek jako řetězec, který je entitizován a pak přidán do XML. Pokud přidáte direktivu typu, FOR XML PATH (''), typevrátí poddotaz výsledek jako typ XML a nedojde k žádné entitizaci.

USE AdventureWorks2022;
GO
SELECT ProductModelID AS "@ProductModelID",
      Name AS "@ProductModelName",
      (SELECT ProductID AS "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')
       ) AS "@ProductIDs",
       (
       SELECT Name AS "ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
       FOR XML PATH (''), type
       ) AS "ProductNames"

FROM Production.ProductModel
WHERE ProductModelID= 7 OR ProductModelID=9
FOR XML PATH('ProductModelData');

Přidejte obory názvů do výsledného XML

Jak je popsáno v tématu Přidávání oborů názvů pomocí FUNKCE XMLNAMESPACES, můžete pomocí funkce WITH XMLNAMESPACES zahrnout obory názvů do dotazů v režimu PATH. Například názvy zadané v klauzuli SELECT zahrnují předpony prostoru názvů. PATH Následující režim dotazu vytvoří XML s obory názvů.

SELECT 'en'    as "English/@xml:lang",
       'food'  as "English",
       'ger'   as "German/@xml:lang",
       'Essen' as "German"
FOR XML PATH ('Translation')
GO

Atribut @xml:lang přidaný do elementu <English> je definován v předdefinovaném oboru názvů XML.

Toto je výsledek:

<Translation>
  <English xml:lang="en">food</English>
  <German xml:lang="ger">Essen</German>
</Translation>

Následující dotaz je podobný příkladu jazyka C s tím rozdílem, že používá WITH XMLNAMESPACES k zahrnutí oborů názvů do výsledku XML. Další informace naleznete v části Přidání oborů názvů do dotazů pomocí WITH XMLNAMESPACES.

USE AdventureWorks2022;
GO
WITH XMLNAMESPACES ('uri1' AS ns1,  DEFAULT 'uri2')
SELECT ProductModelID AS "@ns1:ProductModelID",
      Name AS "@ns1:ProductModelName",
      (SELECT ProductID AS "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')
       ) AS "@ns1:ProductIDs",
       (
       SELECT ProductID AS "@ns1:ProductID",
              Name AS "@ns1:ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID =
              Production.ProductModel.ProductModelID
       FOR XML PATH , type
       ) AS "ns1:ProductNames"
FROM Production.ProductModel
WHERE ProductModelID= 7 OR ProductModelID=9
FOR XML PATH('ProductModelData'), root('root');

Toto je výsledek:

<root xmlns="uri2"
  xmlns:ns1="uri1">
  <ProductModelData ns1:ProductModelID="7" ns1:ProductModelName="HL Touring Frame" ns1:ProductIDs="885 887 888 889 890 891 892 893">
    <ns1:ProductNames>
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="885" ns1:ProductName="HL Touring Frame - Yellow, 60" />
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="887" ns1:ProductName="HL Touring Frame - Yellow, 46" />
      ...
    </ns1:ProductNames>
  </ProductModelData>
  <ProductModelData ns1:ProductModelID="9" ns1:ProductModelName="LL Road Frame" ns1:ProductIDs="722 723 724 725 726 727 728 729 730 736 737 738">
    <ns1:ProductNames>
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="722" ns1:ProductName="LL Road Frame - Black, 58" />
      ...
    </ns1:ProductNames>
  </ProductModelData>
</root>

Viz také