Megosztás a következőn keresztül:


Beágyazott XSD-séma létrehozása

Vonatkozik a következőkre:SQL ServerAzure SQL DatabaseSQL adatbázis a Microsoft Fabric-ben

A FOR XML záradékban kérheti, hogy a lekérdezés beágyazott sémát adjon vissza a lekérdezés eredményeivel együtt. Ha XDR-sémát szeretne, az XMLDATA kulcsszót használja a FOR XML záradékban. Ha XSD-sémát szeretne, használja az XMLSCHEMA kulcsszót.

Ez a cikk az XMLSCHEMA kulcsszót ismerteti, és ismerteti az eredményként kapott beágyazott XSD-séma szerkezetét. A következő korlátozások vonatkoznak a beágyazott sémák igénylésére:

  • Az XMLSCHEMA csak RAW és AUTO módban adható meg, explicit módban nem.

  • Ha egy beágyazott FOR XML-lekérdezés megadja a TYPE direktívát, a lekérdezés eredménye xml típusú, és ezt az eredményt nem beírt XML-adatok példányaként kezeli a rendszer. További információ: XML-adatok (SQL Server).

Amikor XMLSCHEMA-t ad meg egy XML-lekérdezésben, a rendszer séma- és XML-adatokat is kap, a lekérdezés eredményeként. Az adatok minden legfelső szintű eleme az előző sémára hivatkozik egy alapértelmezett névtérdeklaráció használatával, amely viszont a beágyazott séma célnévterére hivatkozik.

Például:

<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
  <xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="https://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
  <xsd:element name="Production.ProductModel">
    <xsd:complexType>
      <xsd:attribute name="ProductModelID" type="sqltypes:int" use="required" />
      <xsd:attribute name="Name" use="required">
        <xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2022].[dbo].[Name]">
          <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
            <xsd:maxLength value="50" />
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:attribute>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
<Production.ProductModel xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" ProductModelID="1" Name="Classic Vest" />

Az eredmény tartalmazza az XML-sémát és az XML-eredményt. Az eredmény <ProductModel> legfelső szintű eleme az xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" alapértelmezett névtérdeklarációval hivatkozik a sémára.

Az eredmény séma része több olyan sémadokumentumot tartalmazhat, amelyek több névteret írnak le. A rendszer legalább a következő két sémadokumentumot adja vissza:

  • Az Sqltypes névtérhez tartozó sémadokumentum, amelyhez az alap SQL-típusok lesznek visszaadva.

  • Egy másik sémadokumentum, amely a FOR XML-lekérdezés eredményének alakját ismerteti.

Továbbá, ha a lekérdezés eredményében bármilyen beírt xml- adattípus szerepel, akkor az ezekhez a beírt xml- adattípusokhoz társított sémák is bekerülnek az eredménybe.

A FOR XML-eredmény alakját leíró sémadokumentum célnévtere rögzített és automatikusan növekményes numerikus részt tartalmaz. A névtér formátuma az alábbiakban látható, ahol n pozitív egész szám. Az előző lekérdezésben például az urn:schemas-microsoft-com:sql:SqlRowSet1 a célnévtér.

urn:schemas-microsoft-com:sql:SqlRowSetn

Előfordulhat, hogy az egyik végrehajtásból a másikba történt eredményben a célnévterek módosítása nem kívánatos. Ha például lekérdezi az eredményként kapott XML-fájlt, a célnévtér módosításához frissítenie kell a lekérdezést. Megadhatja a célnévteret, ha az XMLSCHEMA lehetőséget hozzáadja a FOR XML záradékhoz. Az eredményként kapott XML tartalmazza a megadott névteret, és változatlan marad, függetlenül attól, hogy hányszor futtatja a lekérdezést.

SELECT ProductModelID, Name
FROM   Production.ProductModel
WHERE ProductModelID=1
FOR XML AUTO, XMLSCHEMA ('MyURI');

Entitáselemek

A lekérdezés eredményéhez létrehozott XSD-sémastruktúra részleteinek megvitatásához először le kell írni az entitáselemet

A FOR XML-lekérdezés által visszaadott XML-adatok entitáseleme olyan elem, amely egy táblából jön létre, nem pedig oszlopból. Az alábbi XML-lekérdezés például a Person adatbázis AdventureWorks2025 táblájának névjegyadatait adja vissza.

SELECT BusinessEntityID, FirstName
FROM Person.Person
WHERE BusinessEntityID = 1
FOR XML AUTO, ELEMENTS;

Ez az eredmény:

<Person>
  <BusinessEntityID>1</BusinessEntityID>
  <FirstName>Ken</FirstName>
</Person>

Ebben az eredményben <Person> az entitáselem. Az XML-eredményben több entitáselem is szerepelhet, és ezek mindegyike globális deklarációval rendelkezik a beágyazott XSD-sémában. Az alábbi lekérdezés például lekéri egy adott rendelés értékesítési rendelésének fejlécét és részletes adatait.

SELECT  SalesOrderHeader.SalesOrderID, ProductID, OrderQty
FROM    Sales.SalesOrderHeader, Sales.SalesOrderDetail
WHERE   SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
AND     SalesOrderHeader.SalesOrderID=5001
FOR XML AUTO, ELEMENTS, XMLSCHEMA;

Mivel a lekérdezés az ELEMENTS direktívát adja meg, az eredményként kapott XML elemközpontú. A lekérdezés az XMLSCHEMA-direktívát is meghatározza. Ezért a rendszer egy beágyazott XSD-sémát ad vissza. Ez az eredmény:

<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
  <xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="https://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
  <xsd:element name="Sales.SalesOrderHeader">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="SalesOrderID" type="sqltypes:int" />
        <xsd:element ref="schema:Sales.SalesOrderDetail" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="Sales.SalesOrderDetail">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="ProductID" type="sqltypes:int" />
        <xsd:element name="OrderQty" type="sqltypes:smallint" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Jegyezze fel az előző lekérdezésben szereplő következőket:

  • Az eredményben a <SalesOrderHeader> és a <SalesOrderDetail> entitáselemek. Emiatt globálisan deklarálva vannak a sémában. Ez azt jelzi, hogy a deklaráció a <Schema> elem felső szintjén jelenik meg.

  • A <SalesOrderID>, <ProductID>és <OrderQty> nem entitáselemek, mert oszlopokra vannak leképezve. Az oszlopadatok az ELEMENTS direktíva miatt az XML elemeiként lesznek visszaadva. Ezek az entitáselem összetett típusának helyi elemeire vannak leképezve. Ha az ELEMENTS direktíva nincs megadva, a SalesOrderID, ProductID és OrderQty értékek a megfelelő entitáselem összetett típusának helyi attribútumaihoz vannak leképezve.

Attribútumnév ütközések

Az alábbi vitafórum a CustOrder és CustOrderDetail táblákon alapul. A következő minták teszteléséhez hozza létre ezeket a táblákat, és adja hozzá a saját mintaadatait:

CREATE TABLE CustOrder (OrderID int primary key, CustomerID int);
GO
CREATE TABLE CustOrderDetail (OrderID int, ProductID int, Qty int);
GO

A FOR XML-ben néha ugyanazt a nevet használják különböző tulajdonságok, attribútumok jelzésére. Az alábbi attribútumcentrikus RAW módú lekérdezés például két, azonos nevű, OrderID nevű attribútumot hoz létre. Ez hibát okoz.

SELECT CustOrder.OrderID,
       CustOrderDetail.ProductID,
       CustOrderDetail.OrderID
FROM   dbo.CustOrder, dbo.CustOrderDetail
WHERE  CustOrder.OrderID = CustOrderDetail.OrderID
FOR XML RAW, XMLSCHEMA;

Mivel azonban elfogadható két azonos nevű elem használata, az ELEMENTS direktíva hozzáadásával kiküszöbölheti a problémát:

SELECT CustOrder.OrderID,
       CustOrderDetail.ProductID,
       CustOrderDetail.OrderID
from   dbo.CustOrder, dbo.CustOrderDetail
where  CustOrder.OrderID = CustOrderDetail.OrderID
FOR XML RAW, XMLSCHEMA, ELEMENTS;

Ez az eredmény. A beágyazott XSD-sémában az OrderID elem két alkalommal van definiálva. Az egyik deklarációban a minOccurs értéke 0, amely a CustOrderDetail tábla OrderID azonosítójának felel meg, a második pedig annak a CustOrder táblának az OrderID elsődleges kulcsoszlopára van leképezve, ahol a minOccurs alapértelmezés szerint 1.

<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="https://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
  <xsd:element name="row">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="OrderID" type="sqltypes:int" />
        <xsd:element name="ProductID" type="sqltypes:int" minOccurs="0" />
        <xsd:element name="OrderID" type="sqltypes:int" minOccurs="0" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Elemnév ütközések

A FOR XML-ben ugyanaz a név két alelemet jelölhet. Az alábbi lekérdezés például lekéri a termékek ListPrice és DealerPrice értékeit, de a lekérdezés ugyanazt az aliast adja meg, az Ár értéket a két oszlophoz. Ezért az eredményként kapott sorhalmaznak két azonos nevű oszlopa lesz.

1. eset: Mindkét alelem azonos típusú nem kulcsos oszlop, és null értékű is lehet

A következő lekérdezésben mindkét alelem azonos típusú nem kulcsú oszlop, és null értékű is lehet.

DROP TABLE T;
GO
CREATE TABLE T (ProductID int primary key, ListPrice money, DealerPrice money);
GO
INSERT INTO T values (1, 1.25, null);
GO

SELECT ProductID, ListPrice Price, DealerPrice Price
FROM   T
for    XML RAW, ELEMENTS, XMLSCHEMA;

Ez a megfelelő létrehozott XML. Csak a beágyazott XSD töredéke van megjelenítve:

...
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" />
  <xsd:element name="row">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="ProductID" type="sqltypes:int" />
        <xsd:element name="Price" type="sqltypes:money" minOccurs="0" maxOccurs="2" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
  <ProductID>1</ProductID>
  <Price>1.2500</Price>
</row>

Jegyezze fel a következőket a beágyazott XSD-sémában:

  • A ListPrice és a DealerPrice is azonos típusú, money, és mindkettő null értékű lehet a táblában. Ezért mivel az eredményül kapott XML-fájlban nem lehet visszaadni őket, a <Price> elem összetett típusdeklarációjában csak egy <row> gyermekelem szerepel, amely minOccurs=0 és maxOccurs=2.

  • Az eredményben, mivel a DealerPrice érték NULL értékű a táblában, a rendszer csak ListPrice ad vissza <Price> elemként. Ha hozzáadja a XSINIL paramétert az ELEMENTS-irányelvhez, mindkét olyan elemet megkapja, amelynél az xsi:nil értéke TRUE értékre van állítva a DealerPrice-nek megfelelő<Price> elemhez. A beágyazott XSD-sémában két <Price> gyermekelem is szerepel majd a <row> komplex típusdefinícióban, ahol a nillable attribútum értéke TRUE lesz mindkettő esetében. Ez a töredék eredmény:

...
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" />
  <xsd:element name="row">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="ProductID" type="sqltypes:int" nillable="1" />
        <xsd:element name="Price" type="sqltypes:money" nillable="1" />
        <xsd:element name="Price" type="sqltypes:money" nillable="1" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ProductID>1</ProductID>
  <Price>1.2500</Price>
  <Price xsi:nil="true" />
</row>

2. eset: Egy kulcsoszlop és egy nem kulcsoszlop azonos típusúak

Az alábbi lekérdezés egy azonos típusú kulcsot és egy nem kulcsoszlopot mutat be.

CREATE TABLE T (Col1 int primary key, Col2 int, Col3 nvarchar(20));
GO
INSERT INTO T VALUES (1, 1, 'test');
GO

A következő lekérdezés a T tábla esetében ugyanazt az aliast adja meg az 1. és a 2. oszlophoz, ahol az 1. oszlop elsődleges kulcs, és nem lehet null, a Col2 pedig null értékű. Ez két testvérelemet hoz létre, amelyek a <row> elem gyermekei.

SELECT Col1 as Col, Col2 as Col, Col3
FROM T
FOR XML RAW, ELEMENTS, XMLSCHEMA

Ez az eredmény. Csak a beágyazott XSD-séma töredéke jelenik meg.

...
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" />
  <xsd:element name="row">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Col" type="sqltypes:int" />
        <xsd:element name="Col" type="sqltypes:int" minOccurs="0" />
        <xsd:element name="Col3" minOccurs="0">
          <xsd:simpleType>
            <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
              <xsd:maxLength value="20" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
  <Col>1</Col>
  <Col>1</Col>
  <Col3>test</Col3>
</row>

A beágyazott XSD-sémában vegye figyelembe, hogy a Col2-nek megfelelő <Col> elem minOccurs értéke 0.

3. eset: A különböző típusú és a megfelelő oszlopok mindkét eleme NULL értékű lehet

A következő lekérdezés van megadva a 2. példában látható mintatáblán:

SELECT Col1, Col2 as Col, Col3 as Col
FROM T
FOR XML RAW, ELEMENTS, XMLSCHEMA;

Az alábbi lekérdezésben a Col2 és a Col3 ugyanazokat az aliasokat kapja. Ez két azonos nevű testvérelemet hoz létre, amelyek az eredmény <raw> elemének mindkét gyermeke. Mindkét oszlop különböző típusú, és mindkettő null értékű lehet. Ez az eredmény. Csak részleges beágyazott XSD-séma jelenik meg.

...
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" />
  <xsd:simpleType name="Col1">
    <xsd:restriction base="sqltypes:int" />
  </xsd:simpleType>
  <xsd:simpleType name="Col2">
    <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
      <xsd:maxLength value="20" />
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:element name="row">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Col1" type="sqltypes:int" />
        <xsd:element name="Col" minOccurs="0" maxOccurs="2" type="xsd:anySimpleType" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
  <Col1>1</Col1>
  <Col xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Col1">1</Col>
  <Col xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Col2">test</Col>
</row>

Jegyezze fel a következőket a beágyazott XSD-sémában:

  • Mivel a Col2 és a Col3 is null értékű lehet, a <Col> elemdeklaráció a minOccurs értéket 0, a maxOccurs 2 értéket adja meg.

  • Mivel mindkét <Col> elem testvér, a sémában egy elemdeklaráció található. Mivel mindkét elem különböző típusú is, bár mindkettő egyszerű típusok, a séma elemének típusa xsd:anySimpleType. Az eredményben minden példánytípust a xsi:type attribútum azonosít.

  • Az eredményben a <Col> elem minden példánya a példánytípusára hivatkozik a xsi:type attribútum használatával.