Udostępnij za pośrednictwem


Wyrażenia SequenceType (XQuery)

Dotyczy:programu SQL Server

W trybie XQuery wartość jest zawsze sekwencją. Typ wartości jest określany jako typ sekwencji. Typ sekwencji może być używany w wystąpieniu wyrażenia XQuery. Składnia SequenceType opisana w specyfikacji XQuery jest używana, gdy trzeba odwołać się do typu w wyrażeniu XQuery.

Nazwa typu niepodzielnego może być również używana w rzutowanie jako wyrażenie XQuery. W programie SQL Server wystąpienie i rzutowane jako wyrażenia XQuery w typach SequenceType są częściowo obsługiwane.

wystąpienie operatora

Wystąpienie operatora może służyć do określania dynamicznego lub uruchomieniowego typu wartości określonego wyrażenia. Na przykład:

  
Expression instance of SequenceType[Occurrence indicator]  

Należy pamiętać, że operator instance of, Occurrence indicator, określa kardynalność, liczbę elementów w sekwencji wynikowej. Jeśli ta wartość nie zostanie określona, przyjmuje się, że kardynalność wynosi 1. W programie SQL Server obsługiwany jest tylko znacznik zapytania (?) wskaźnik wystąpienia. ? wskaźnik wystąpienia wskazuje, że Expression może zwrócić zero lub jeden element. Jeśli ? określono wskaźnik wystąpienia, instance of zwraca wartość True, gdy typ Expression jest zgodny z określonym SequenceType, niezależnie od tego, czy Expression zwraca pojedynczą lub pustą sekwencję.

Jeśli ? nie określono wskaźnika wystąpienia, sequence of zwraca wartość True tylko wtedy, gdy typ Expression jest zgodny z określonym Type i Expression zwraca pojedynczy.

Uwaga symbol plus (+) i gwiazdka (*) wskaźniki wystąpienia nie są obsługiwane w programie SQL Server.

W poniższych przykładach pokazano użyciewystąpienia operatora XQuery.

Przykład A

Poniższy przykład tworzy zmienną typu xml i określa zapytanie względem niej. Wyrażenie zapytania określa operator instance of w celu określenia, czy typ dynamiczny wartości zwracanej przez pierwszy operand pasuje do typu określonego w drugim operandzie.

Następujące zapytanie zwraca wartość True, ponieważ wartość 125 jest wystąpieniem określonego typu, xs:integer:

declare @x xml  
set @x=''  
select @x.query('125 instance of xs:integer')  
go  

Następujące zapytanie zwraca wartość True, ponieważ wartość zwrócona przez wyrażenie /a[1] w pierwszym operandzie jest elementem:

declare @x xml  
set @x='<a>1</a>'  
select @x.query('/a[1] instance of element()')  
go  

Podobnie instance of zwraca wartość True w poniższym zapytaniu, ponieważ typ wartości wyrażenia w pierwszym wyrażeniu jest atrybutem:

declare @x xml  
set @x='<a attr1="x">1</a>'  
select @x.query('/a[1]/@attr1 instance of attribute()')  
go  

W poniższym przykładzie wyrażenie, data(/a[1], zwraca niepodzieną wartość, która jest typowana jako xdt:untypedAtomic. W związku z tym instance of zwraca wartość True.

declare @x xml  
set @x='<a>1</a>'  
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')  
go  

W poniższym zapytaniu wyrażenie data(/a[1]/@attrAzwraca nietypową wartość nietypową. W związku z tym instance of zwraca wartość True.

declare @x xml  
set @x='<a attrA="X">1</a>'  
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')  
go  

Przykład B

W tym przykładzie zapytanie dotyczy kolumny XML wpisanej w przykładowej bazie danych AdventureWorks. Kolekcja schematów XML skojarzona z kwerendą kolumny zawiera informacje o wpisywaniu.

W wyrażeniu data() zwraca wartość typową atrybutu ProductModelID, którego typem jest xs:string zgodnie ze schematem skojarzonym z kolumną. W związku z tym instance of zwraca wartość True.

SELECT CatalogDescription.query('  
   declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
   data(/PD:ProductDescription[1]/@ProductModelID) instance of xs:string  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

Aby uzyskać więcej informacji, zobacz Compare Typed XML to Untyped XML.

Następujące zapytania używają wyrażenia warunkowego instance of, aby określić, czy atrybut LocationID ma typ xs:integer:

SELECT Instructions.query('  
   declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
   /AWMI:root[1]/AWMI:Location[1]/@LocationID instance of attribute(LocationID,xs:integer)  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID=7  

Następujące zapytanie jest określane względem kolumny XML typu CatalogDescription. Kolekcja schematów XML skojarzona z tą kolumną zawiera informacje o wpisywaniu.

Zapytanie używa testu element(ElementName, ElementType?) w wyrażeniu instance of, aby sprawdzić, czy /PD:ProductDescription[1] zwraca węzeł elementu określonej nazwy i typu.

SELECT CatalogDescription.query('  
     declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
     /PD:ProductDescription[1] instance of element(PD:ProductDescription, PD:ProductDescription?)  
    ') as Result  
FROM  Production.ProductModel  
where ProductModelID=19  

Zapytanie zwraca wartość True.

Przykład C

W przypadku używania typów unii wyrażenie instance of w programie SQL Server ma ograniczenie: w szczególności, gdy typ elementu lub atrybutu jest typem unii, instance of może nie określić dokładnego typu. W związku z tym zapytanie zwróci wartość False, chyba że typy niepodzielne używane w sekwencji SequenceType są najwyższym elementem nadrzędnym rzeczywistego typu wyrażenia w hierarchii simpleType. Oznacza to, że typy niepodzielne określone w typie SequenceType muszą być bezpośrednim elementem podrzędnym anySimpleType. Aby uzyskać informacje o hierarchii typów, zobacz Type Casting Rules in XQuery.

Następny przykład zapytania wykonuje następujące czynności:

  • Utwórz kolekcję schematów XML z typem unii, takim jak liczba całkowita lub typ ciągu, zdefiniowany w nim.

  • Zadeklaruj typową zmienną xml przy użyciu kolekcji schematów XML.

  • Przypisz przykładowe wystąpienie XML do zmiennej.

  • Wykonaj zapytanie względem zmiennej, aby zilustrować zachowanie instance of podczas pracy z typem unii.

Jest to zapytanie:

CREATE XML SCHEMA COLLECTION MyTestSchema AS '  
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ns" xmlns:ns="http://ns">  
<simpleType name="MyUnionType">  
<union memberTypes="integer string"/>  
</simpleType>  
<element name="TestElement" type="ns:MyUnionType"/>  
</schema>'  
Go  

Następujące zapytanie zwraca wartość False, ponieważ typ SequenceType określony w wyrażeniu instance of nie jest najwyższym elementem nadrzędnym rzeczywistego typu określonego wyrażenia. Oznacza to, że wartość <TestElement> jest typem całkowitym. Najwyższy element nadrzędny to xs:decimal. Nie jest jednak określony jako drugi operand operatora instance of.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
  
SELECT @var.query('declare namespace ns="http://ns"   
   data(/ns:TestElement[1]) instance of xs:integer')  
go  

Ponieważ najwyższy element nadrzędny xs:integer to xs:decimal, zapytanie zwróci wartość True, jeśli zmodyfikujesz zapytanie i określisz wartość xs:decimal jako typ sekwencji w zapytaniu.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
SELECT @var.query('declare namespace ns="http://ns"     
   data(/ns:TestElement[1]) instance of xs:decimal')  
go  

Przykład D

W tym przykładzie najpierw utworzysz kolekcję schematów XML i użyjesz jej do wpisywania zmiennej xml. Następnie jest odpytywane xml zmiennej w celu zilustrowania funkcji instance of.

Następująca kolekcja schematów XML definiuje prosty typ, typ myType i element, <root>, typu myType:

drop xml schema collection SC  
go  
CREATE XML SCHEMA COLLECTION SC AS '  
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNS" xmlns:ns="myNS"  
xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">  
      <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>  
      <simpleType name="myType">  
           <restriction base="s:varchar">  
                  <maxLength value="20"/>  
            </restriction>  
      </simpleType>  
      <element name="root" type="ns:myType"/>  
</schema>'  
Go  

Teraz utwórz wpisaną zmienną xml i wykonaj względem niej zapytanie:

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
   data(/ns:root[1]) instance of ns:myType')  
go  

Ponieważ typ myType pochodzi z ograniczeń od typu varchar zdefiniowanego w schemacie sqltypes, instance of również zwróci wartość True.

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
data(/ns:root[1]) instance of sqltypes:varchar?')  
go  

Przykład E

W poniższym przykładzie wyrażenie pobiera jedną z wartości atrybutu IDREFS i używa instance of do określenia, czy wartość jest typu IDREF. W przykładzie są wykonywane następujące operacje:

  • Tworzy kolekcję schematów XML, w której element <Customer> ma atrybut typu OrderList IDREFS, a element <Order> ma atrybut typu identyfikatora OrderID.

  • Tworzy typową zmienną xml i przypisuje do niej przykładowe wystąpienie XML.

  • Określa zapytanie względem zmiennej. Wyrażenie zapytania pobiera wartość pierwszego identyfikatora zamówienia z atrybutu typu OrderList IDREFS pierwszego <Customer>. Pobrana wartość jest typem IDREF. W związku z tym instance of zwraca wartość True.

create xml schema collection SC as  
'<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:Customers="Customers" targetNamespace="Customers">  
            <element name="Customers" type="Customers:CustomersType"/>  
            <complexType name="CustomersType">  
                        <sequence>  
                            <element name="Customer" type="Customers:CustomerType" minOccurs="0" maxOccurs="unbounded" />  
                        </sequence>  
            </complexType>  
             <complexType name="OrderType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="OrderValue" type="integer" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="OrderID" type="ID" />  
            </complexType>  
  
            <complexType name="CustomerType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="spouse" type="string" minOccurs="0" maxOccurs="unbounded"/>  
                                <element name="Order" type="Customers:OrderType" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="CustomerID" type="string" />  
                <attribute name="OrderList" type="IDREFS" />  
            </complexType>  
 </schema>'  
go  
declare @x xml(SC)  
set @x='<CustOrders:Customers xmlns:CustOrders="Customers">  
                <Customer CustomerID="C1" OrderList="OrderA OrderB"  >  
                              <spouse>Jenny</spouse>  
                                <Order OrderID="OrderA"><OrderValue>11</OrderValue></Order>  
                                <Order OrderID="OrderB"><OrderValue>22</OrderValue></Order>  
  
                </Customer>  
                <Customer CustomerID="C2" OrderList="OrderC OrderD" >  
                                <spouse>John</spouse>  
                                <Order OrderID="OrderC"><OrderValue>33</OrderValue></Order>  
                                <Order OrderID="OrderD"><OrderValue>44</OrderValue></Order>  
  
                        </Customer>  
                <Customer CustomerID="C3"  OrderList="OrderE OrderF" >  
                                <spouse>Jane</spouse>  
                                <Order OrderID="OrderE"><OrderValue>55</OrderValue></Order>  
                                <Order OrderID="OrderF"><OrderValue>55</OrderValue></Order>  
                </Customer>  
                <Customer CustomerID="C4"  OrderList="OrderG"  >  
                                <spouse>Tim</spouse>  
                                <Order OrderID="OrderG"><OrderValue>66</OrderValue></Order>  
                        </Customer>  
                <Customer CustomerID="C5"  >  
                </Customer>  
                <Customer CustomerID="C6" >  
                </Customer>  
                <Customer CustomerID="C7"  >  
                </Customer>  
</CustOrders:Customers>'  
  
select @x.query(' declare namespace CustOrders="Customers";   
 data(CustOrders:Customers/Customer[1]/@OrderList)[1] instance of xs:IDREF ? ') as XML_result  

Ograniczenia implementacji

Są to ograniczenia:

  • Typy sekwencji schema-element() i schema-attribute() nie są obsługiwane w porównaniu z operatorem instance of.

  • Pełne sekwencje, na przykład (1,2) instance of xs:integer*, nie są obsługiwane.

  • W przypadku używania formularza elementu () typu sekwencji, który określa nazwę typu, taką jak element(ElementName, TypeName), typ musi być kwalifikowany z znakiem zapytania (?). Na przykład element(Title, xs:string?) wskazuje, że element może mieć wartość null. Program SQL Server nie obsługuje wykrywania w czasie wykonywania właściwości xsi:nil przy użyciu instance of.

  • Jeśli wartość w Expression pochodzi z elementu lub atrybutu typizowanego jako unia, program SQL Server może zidentyfikować tylko typ pierwotny, a nie pochodny, z którego typ wartości pochodzi. Jeśli na przykład <e1> jest zdefiniowany tak, aby miał statyczny typ (xs:integer | xs:string), następujące polecenie zwróci wartość False.

    data(<e1>123</e1>) instance of xs:integer  
    

    Jednak data(<e1>123</e1>) instance of xs:decimal zwróci wartość True.

  • W przypadku typów sekwencji processing-instruction() i document-node() są dozwolone tylko formularze bez argumentów. Na przykład processing-instruction() jest dozwolona, ale processing-instruction('abc') jest niedozwolona.

rzutowanie jako operator

Rzutowanie jako wyrażenie może służyć do konwertowania wartości na określony typ danych. Na przykład:

  
Expression cast as  AtomicType?  

W programie SQL Server znak zapytania (?) jest wymagany po AtomicType. Na przykład, jak pokazano w poniższym zapytaniu, "2" cast as xs:integer? konwertuje wartość ciągu na liczbę całkowitą:

declare @x xml  
set @x=''  
select @x.query('"2" cast as xs:integer?')  

W poniższym zapytaniu data() zwraca wartość typową atrybutu ProductModelID, typ ciągu. Operator cast askonwertuje wartość na xs:integer.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)  
SELECT CatalogDescription.query('  
   data(/PD:ProductDescription[1]/@ProductModelID) cast as xs:integer?  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

Jawne użycie data() nie jest wymagane w tym zapytaniu. Wyrażenie cast as wykonuje niejawną atomizację w wyrażeniu wejściowym.

Funkcje konstruktora

Można użyć funkcji konstruktora typu niepodzielnego. Na przykład zamiast używać operatora cast as, "2" cast as xs:integer?można użyć funkcji konstruktora xs:integer(), jak w poniższym przykładzie:

declare @x xml  
set @x=''  
select @x.query('xs:integer("2")')  

Poniższy przykład zwraca wartość xs:date równą 2000-01-01Z.

declare @x xml  
set @x=''  
select @x.query('xs:date("2000-01-01Z")')  

Można również użyć konstruktorów dla typów niepodzielnych zdefiniowanych przez użytkownika. Jeśli na przykład kolekcja schematów XML skojarzona z typem danych XML definiuje prosty typ, można użyć myType() konstruktora w celu zwrócenia wartości tego typu.

Ograniczenia implementacji

  • Wyrażenia XQuery przełączniki typu, rzutowalnei traktują nie są obsługiwane.

  • rzutowanie jako wymaga znaku zapytania (?) po typie niepodzielnej.

  • xs:QName nie jest obsługiwany jako typ rzutu. Zamiast tego użyj rozszerzonej nazwy QName.

  • xs:date, xs:timei xs:datetime wymagają strefy czasowej wskazanej przez Z.

    Następujące zapytanie kończy się niepowodzeniem, ponieważ nie określono strefy czasowej.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>')  
    go  
    

    Dodając wskaźnik strefy czasowej Z do wartości, zapytanie działa.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>')  
    go  
    

    Jest to wynik:

    <a>2002-05-25Z</a>  
    

Zobacz też

wyrażenia XQuery
system typów (XQuery)