SequenceType výrazy (XQuery)
platí pro:SQL Server
V XQuery je hodnota vždy posloupnost. Typ hodnoty se označuje jako typ sekvence. Typ sekvence lze použít v instanci výrazu XQuery. Syntaxe SequenceType popsaná ve specifikaci XQuery se používá, když potřebujete odkazovat na typ ve výrazu XQuery.
Název atomového typu lze také použít v přetypování jako výraz XQuery. V SQL Serveru je instance a převedena jako výrazy XQuery na SequenceTypes částečně podporována.
instance operátoru
instanci operátoru lze použít k určení dynamického nebo běhu typu hodnoty zadaného výrazu. Například:
Expression instance of SequenceType[Occurrence indicator]
Všimněte si, že operátor instance of
, Occurrence indicator
, určuje kardinalitu, počet položek ve výsledné sekvenci. Pokud není zadáno, předpokládá se, že kardinalita je 1. V SQL Serveru se podporuje pouze otazník (?) indikátor výskytu.
? indikátor výskytu označuje, že Expression
může vrátit nulovou nebo jednu položku. Pokud je zadán indikátor výskytu ?, instance of
vrátí True, když typ Expression
odpovídá zadanému SequenceType
, bez ohledu na to, zda Expression
vrátí jednotlivý prvek nebo prázdnou sekvenci.
Pokud ? indikátor výskytu není zadán, sequence of
vrátí hodnotu True pouze v případě, že typ Expression
odpovídá zadanému Type
a Expression
vrátí singleton.
Poznámka Indikátory výskytu symbolu plus (+) a hvězdičky (*) nejsou v SQL Serveru podporovány.
Následující příklady ilustrují použitíinstance XQuery operátoru.
Příklad A
Následující příklad vytvoří xml typ proměnné a specifikuje dotaz na ni. Výraz dotazu určuje operátor instance of
, který určuje, zda dynamický typ hodnoty vrácené prvním operandem odpovídá typu zadanému ve druhém operandu.
Následující dotaz vrátí hodnotu True, protože hodnota 125 je instance zadaného typu, xs:integer:
declare @x xml
set @x=''
select @x.query('125 instance of xs:integer')
go
Následující dotaz vrátí hodnotu True, protože hodnota vrácená výrazem /a[1] je v prvním operandu prvek:
declare @x xml
set @x='<a>1</a>'
select @x.query('/a[1] instance of element()')
go
Podobně instance of
vrátí hodnotu True v následujícím dotazu, protože typ hodnoty výrazu v prvním výrazu je atribut:
declare @x xml
set @x='<a attr1="x">1</a>'
select @x.query('/a[1]/@attr1 instance of attribute()')
go
V následujícím příkladu výraz, data(/a[1]
, vrátí atomickou hodnotu, která je zadána jako xdt:untypedAtomic. Proto instance of
vrátí hodnotu True.
declare @x xml
set @x='<a>1</a>'
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')
go
V následujícím dotazu výraz data(/a[1]/@attrA
vrátí netypovou atomovou hodnotu. Proto instance of
vrátí hodnotu True.
declare @x xml
set @x='<a attrA="X">1</a>'
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')
go
Příklad B
V tomto příkladu dotazujete zadaný sloupec XML v ukázkové databázi AdventureWorks. Kolekce schématu XML přidružená ke sloupci, který se dotazuje, poskytuje informace o psaní.
Ve výrazu data() vrátí zadaná hodnota atributu ProductModelID, jehož typ je xs:string podle schématu přidruženého ke sloupci. Proto instance of
vrátí hodnotu 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
Další informace najdete v části Porovnání typovaného XML s netypovaným XML.
Následující dotazy používají logický výraz instance of
k určení, jestli je atribut LocationID typu 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
Následující dotaz je zadán ve sloupci XML typu CatalogDescription. Kolekce schématu XML přidružená k tomuto sloupci poskytuje informace o psaní.
Dotaz používá element(ElementName, ElementType?)
test ve výrazu instance of
k ověření, že /PD:ProductDescription[1]
vrací uzel prvku konkrétního názvu a 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
Dotaz vrátí hodnotu True.
Příklad C
Při použití typů sjednocení má výraz instance of
v SQL Serveru omezení: Konkrétně, pokud typ prvku nebo atributu je typ sjednocení, instance of
nemusí určit přesný typ. V důsledku toho dotaz vrátí hodnotu False, pokud atomické typy použité v SequenceType jsou nejvyšším nadřazeným typem skutečného typu výrazu v hierarchii simpleType. To znamená, že atomické typy zadané v sequenceType musí být přímým podřízeným objektem anySimpleType. Informace o hierarchii typů naleznete v tématu Pravidla přetypování typů v XQuery.
Následující příklad dotazu provede následující:
Vytvořte kolekci schématu XML s typem sjednocení, jako je celé číslo nebo typ řetězce, který je v něm definovaný.
Deklarujte typovou xml proměnnou pomocí kolekce schémat XML.
Přiřaďte k proměnné ukázkovou instanci XML.
Zadejte dotaz na proměnnou, která ilustruje chování
instance of
při práci s typem sjednocení.
Toto je dotaz:
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
Následující dotaz vrátí hodnotu False, protože SequenceType zadaný ve výrazu instance of
není nejvyšší nadřazenou hodnotou skutečného typu zadaného výrazu. To znamená, že hodnota <TestElement
> je celočíselného typu. Nejvyšší nadřazený prvek je xs:decimal. Není však zadán jako druhý operand operátoru 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
Vzhledem k tomu, že nejvyšší nadřazená hodnota xs:integer je xs:decimal, dotaz vrátí hodnotu True, pokud upravíte dotaz a zadáte xs:decimal jako sequenceType v dotazu.
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
Příklad D
V tomto příkladu nejprve vytvoříte kolekci schémat XML a použijete ji k zadání xml proměnné. Typová proměnná xml se pak dotazuje, aby ilustrovala funkci instance of
.
Následující kolekce schémat XML definuje jednoduchý typ, myType a 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
Teď vytvořte typovou xml proměnnou a dotazujte se na ni:
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
Vzhledem k tomu, že typ myType je odvozen omezením z varchar typu, který je definován ve schématu sqltypes, instance of
vrátí také hodnotu 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
Příklad E
V následujícím příkladu výraz načte jednu z hodnot atributu IDREFS a používá instance of
k určení, zda je hodnota typu IDREF. Příklad provede následující:
Vytvoří kolekci schémat XML, ve které má prvek <
Customer
> atribut typu IDREFS s názvem OrderList, a element <Order
> má atribut typu ID s názvem OrderID.Vytvoří typovou xml proměnnou a přiřadí k ní ukázkovou instanci XML.
Specifikuje dotaz na proměnnou. Výraz dotazu načte hodnotu ID první objednávky z atributu typu OrderList IDREFS prvního <
Customer
>. Načtená hodnota je typ IDREF. Protoinstance of
vrátí hodnotu 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
Omezení implementace
Toto jsou omezení:
schema-element() a schema-attribute() typy sekvence nejsou podporovány pro porovnání s operátorem
instance of
.Úplné sekvence, například
(1,2) instance of xs:integer*
, nejsou podporovány.Pokud používáte formu element() typ sekvence, který určuje název typu, například
element(ElementName, TypeName)
, musí být typ kvalifikovaný pomocí otazníku (?). Napříkladelement(Title, xs:string?)
označuje, že prvek může mít hodnotu null. SQL Server nepodporuje zjišťování za běhu vlastnosti xsi:nil pomocíinstance of
.Pokud hodnota v
Expression
pochází z elementu nebo atributu zadaného jako sjednocení, SQL Server dokáže identifikovat pouze primitivní, nikoli odvozený typ, ze kterého byl odvozen typ hodnoty. Pokud je například definován <e1
>, aby měl statický typ (xs:integer | xs:string), vrátí se následující hodnota False.data(<e1>123</e1>) instance of xs:integer
data(<e1>123</e1>) instance of xs:decimal
však vrátí hodnotu True.Pro typy sekvence processing-instruction() a document-node() jsou povoleny pouze formy bez argumentů. Například
processing-instruction()
je povolená, aleprocessing-instruction('abc')
není povolená.
přetypování jako operátor
Přetypování jako výraz lze použít k převodu hodnoty na konkrétní datový typ. Například:
Expression cast as AtomicType?
Na SQL Serveru se po AtomicType
vyžaduje otazník (?). Například, jak je znázorněno v následujícím dotazu, "2" cast as xs:integer?
převede řetězcovou hodnotu na celé číslo:
declare @x xml
set @x=''
select @x.query('"2" cast as xs:integer?')
V následujícím dotazu data() vrátí zadanou hodnotu atributu ProductModelID jako je typ řetězce. Operátor cast as
převede hodnotu 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
Explicitní použití dat() není v tomto dotazu povinné. Výraz cast as
provádí implicitní atomizaci vstupního výrazu.
Funkce konstruktoru
Můžete použít funkce konstruktoru atomických typů. Například místo použití operátoru cast as
"2" cast as xs:integer?
můžete použít funkci xs:integer() konstruktoru, jak je znázorněno v následujícím příkladu:
declare @x xml
set @x=''
select @x.query('xs:integer("2")')
Následující příklad vrátí hodnotu xs:date rovna 2000-01-01Z.
declare @x xml
set @x=''
select @x.query('xs:date("2000-01-01Z")')
Můžete také použít konstruktory pro uživatelem definované atomické typy. Pokud například kolekce schématu XML přidružená k datovému typu XML definuje jednoduchý typ, lze k vrácení hodnoty tohoto typu použít myType() konstruktor.
Omezení implementace
Výrazy XQuery typeswitch, převeditelnéa ošetření nejsou podporovány.
přetypování na vyžaduje po atomickém typu otazník (?).
xs:QName není podporován jako typ pro přetypování. Místo toho použijte rozbalený -QName.
xs:date, xs:timea xs:datetime vyžadují časové pásmo, které je označené písmenem Z.
Následující dotaz selže, protože není zadané časové pásmo.
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>') go
Když k hodnotě přidáte indikátor časového pásma Z, dotaz funguje.
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>') go
Toto je výsledek:
<a>2002-05-25Z</a>