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]/@attrA
zwraca 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 tyminstance 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ładelement(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życiuinstance 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, aleprocessing-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 as
konwertuje 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)