Inline XSD Schema Generation

W klauzula FOR XML można zażądać, że kwerenda zwraca schematu wbudowanej wraz z wyniki kwerendy.Chcąc schematu XDR słowo kluczowe XMLDATA zostanie użyte w klauzula FOR XML.Chcąc schematu XSD, można użyć słowa kluczowego XMLSCHEMA.

W tym temacie opisano kluczowe XMLSCHEMA i wyjaśniono Struktura wynikowa schematu XSD wbudowany.Poniżej przedstawiono ograniczenia, gdy żądają wbudowanych schematów:

  • Można określić XMLSCHEMA tylko w trybie RAW i AUTO, a nie w trybie JAWNE.

  • Jeśli zagnieżdżonych kwerendy FOR XML określa dyrektywę TYPE, wynik kwerendy jest XML typu, a wynik jest traktowana jako wystąpienie bez typu danych XML.Aby uzyskać więcej informacji zobaczImplementing XML in SQL Server.

Po określeniu XMLSCHEMA w kwerendzie FOR XML otrzymujesz schemat oraz dane XML, w wyniku kwerendy.Każdy element najwyższego poziom dane odnosi się do poprzedniego schematu przy użyciu domyślnego deklaracja obszaru nazw, które z kolei odwołuje się do miejsce docelowe obszar nazw schematu wbudowanej.

Na przykład:

<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="[AdventureWorks].[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" />

Wynik zawiera schemat XML i wynik XML.The <ProductModel> top-poziom element in the result refers to the schema by using the default namespace deklaracja, xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" .

Część schematu z wyników może zawierać wiele dokumentów schematu, które opisują wiele obszarów nazw.Co najmniej zwracane są następujące dokumenty dwóch schematu:

  • Dokument jednego schematu dla Sqltypes obszaru nazw, i które są zwracane typy podstawowe SQL.

  • Inny dokument schemat opisujący kształt FOR XML wyników kwerendy.

Ponadto jeśli wpisany XML typy danych są zawarte w wyniku kwerendy schematów, skojarzone z tymi wpisywanych XML typy danych są uwzględniane.

miejsce docelowe obszar nazw dokument schematu, opisujący kształt wynik XML dla zawiera części stałej i liczbowe fragment, który zwiększa się automatycznie.Format ten obszar nazw jest wyświetlana w następującej gdzie n jest dodatnią liczbą całkowitą.Na przykład w poprzedniej kwerendy com:sql:SqlRowSet1 urn: schemas - microsoft - jest miejsce docelowe obszar nazw.

urn:schemas-microsoft-com:sql:SqlRowSetn

Zmiany w obszarach nazw miejsce docelowe, w wyniku wystąpienia z wykonanie jednego do drugiego może nie być pożądane.Na przykład, jeśli kwerendy XML Wynikowe, zmiana miejsce docelowe obszaru nazw wymaga aktualizację kwerendy.Opcjonalnie można określić docelowego obszaru nazw, po dodaniu opcji XMLSCHEMA w klauzula FOR XML.Wynikowy plik XML zostaną uwzględnione w obszarze nazw została podana i pozostanie takie same, niezależnie od tego, ile razy wykonywania kwerendy.

select ProductModelID, Name
from   Production.ProductModel
where ProductModelID=1
FOR XML AUTO, XMLSCHEMA ('MyURI')

obiekt Elementów

W celu omówienia szczegółowe informacje o strukturze schematu XSD generowany w wyniku kwerendy, ma być opisanej po raz pierwszy element obiekt

Element obiekt w danych XML zwróconych przez kwerendę FOR XML jest element, który jest generowany z tabela, a nie z kolumna.Na przykład, poniższa kwerenda FOR XML zwraca informacje o kontakcie z Kontakt tabela in AdventureWorks bazy danych.

SELECT ContactID, FirstName
FROM Person.Contact
WHERE ContactID = 1
FOR XML AUTO, ELEMENTS

Oto wynik:

  <Contact>
    <ContactID>1</ContactID>
    <FirstName>Syed</FirstName>
  </Contact>

W tym wynik <Contact> jest to element obiekt. Może istnieć wiele obiekt elementów w wyniku XML i każdego z nich ma globalne deklaracja w wbudowanego schematu XSD.Na przykład poniższa kwerenda pobiera informacje nagłówka i szczegóły zamówień sprzedaży dla określonego zamówienia.

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

Kwerenda określa dyrektywę ELEMENTS, więc wynikowy kod XML jest skoncentrowany na elementach.Kwerenda określa także dyrektywę XMLSCHEMA.Dlatego jest zwracany wbudowany schemat XSD.Oto wynik:

<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>

Należy uwzględnić następujące z poprzedniej kwerendy:

  • W wyniku, <SalesOrderHeader> i <SalesOrderDetail> są elementami obiekt. W związku z tym które są globalnie zadeklarowane w schemacie.Oznacza to, deklaracja pojawia się u góry poziom wewnątrz <Schema> element.

  • The <SalesOrderID>, <ProductID>, and <OrderQty> are not obiekt elements, because they map to columns. kolumna danych są zwracane jako elementy XML, z powodu dyrektywa elementów.Te są mapowane na elementy lokalne obiekt elementu typu złożonego.Należy zauważyć, że jeśli dyrektywa elementów nie jest określony, SalesOrderID, IDProduktu and OrderQty wartości są mapowane na lokalne atrybutów odpowiedniego elementu obiektu typu złożonego.

Atrybut kolizji nazw

Na podstawie następujących dyskusji CustOrder and CustOrderDetail tabel.Aby przetestować następujące próbki, tworzenie tych tabel i dodać dane przykładowe:

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

XML dla tej samej nazwie czasami umożliwia wskazują inne właściwości, atrybutów.Na przykład poniższa kwerenda zorientowane na atrybut trybu RAW generuje dwa atrybuty, które mają taką samą nazwę, identyfikator zamówienia.Spowoduje to wygenerowanie błędu.

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

Jednak ponieważ akceptowane są dwa elementy, które mają taką samą nazwę, można wyeliminować problem przez dodanie dyrektywa elementów:

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

Jest to wynik.Uwaga w wbudowanego schematu XSD, identyfikator zamówienia, element jest określony dwa razy.Jeden z deklaracji ma wartość parametru minOccurs zestaw na 0, odpowiadającą identyfikator zamówienia z tabela CustOrderDetail i drugi mapuje IDZamówienia podstawowego kolumna klucz z CustOrder tabela, gdy wartość parametru minOccurs jest 1 domyślnie.

<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>

Element kolizji nazw

XML dla tej samej nazwie może służyć do wskazania dwa podelementy.Na przykład poniższa kwerenda pobiera wartości ListPrice i DealerPrice produktów, ale kwerendy określa alias takie same, cena, dla tych dwóch kolumn.Wynikowy zestaw wierszy będą więc dwie kolumny o tej samej nazwie.

przypadek 1: Oba podelementy nonkey kolumny są tego samego typu i może być NULL

W następującej kwerendzie obu podelementy nonkey kolumny są tego samego typu i może mieć wartości NULL.

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

Jest to odpowiedniego kodu XML wygenerowany.Wyświetlany jest tylko część wbudowany XSD:

…
<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>

Należy uwzględnić następujące metody w wierszach schematu XSD:

  • ListPrice i DealerPrice są tego samego typu pieniądze, a jednocześnie może mieć wartość NULL w tabela.Dlatego ponieważ mogą one nie będą zwracane w wynikowym pliku XML, jest tylko jeden <Price> element podrzędność w deklaracja typu złożonego <row> element, który ma wartość parametru minOccurs = 0 i maxOccurs = 2.

  • W wyniku ponieważ DealerPrice wartość NULL w tabela tylko ListPrice są zwracane jako element <Price> .Jeśli dodasz XSINIL parametr dyrektywa elementów, wyświetlony zostanie zarówno elementy, które mają xsi: nil wartość zestaw na wartość TRUE dla elementu<Price> , który odpowiada DealerPrice.Także pojawić się dwa <Price> elementy podrzędność w <row> Definicja typu złożonego w schemacie wbudowany XSD z nillable atrybut zestaw na wartość TRUE dla obu. Ten fragment jest wynik częściowy:

…
<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>

przypadek 2: Jeden z kluczy i jedną kolumna nonkey tego samego typu

Następująca kwerenda ilustruje jeden klucz i jedną kolumna nonkey tego samego typu.

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

Następująca kwerenda tabela T określa samego alias Kol1 i Kol2, gdzie Kol1 jest klucz podstawowy i nie może mieć wartości null, a Kol2 może mieć wartości null.Spowoduje to wygenerowanie dwa elementy tego samego poziomu, które są podrzędne <row> element.

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

Jest to wynik.Jest wyświetlany tylko fragment wbudowanego schematu XSD.

…
<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>

Uwaga do wbudowanego schematu XSD, <Col> element odpowiadający Kol2 ma wartość parametru minOccurs ustawiona na 0.

przypadek 3: Oba elementy różnych typów i odpowiadające im kolumny może mieć wartości NULL

W następującej kwerendzie określono przed przykładową tabela, przypadek 2:

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

W następującej kwerendzie Kol2 i Col3 podane są te same aliasów.Spowoduje to wygenerowanie mają taką samą nazwę, a oba elementy podrzędne, które są dwa elementy tego samego poziomu <raw> element w wyniku. Obie te kolumny są różnych typów i może być NULL.Jest to wynik.Jest wyświetlany tylko częściowego wbudowanego schematu XSD.

…
<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>

Należy uwzględnić następujące metody w wierszach schematu XSD:

  • Ponieważ zarówno Kol2 i Col3 może mieć wartość NULL, <Col> Deklaracja elementu określa wartość parametru minOccurs jako 0 i maxOccurs jako 2.

  • Ponieważ zarówno <Col> elementy są tym samym poziomie, co deklaracja elementu w schemacie. Ponieważ oba te elementy są również różnego typu, mimo że obie są także proste typy jest typ elementu w schemacie xsd:anySimpleType.W wyniku, każdy typ obiektu jest identyfikowany przez Typ xsi: type atrybut.

  • W wyniku każde wystąpienie <Col> element odnosi się do jego typu wystąpienia przy użyciu Typ xsi: type atrybut.