Sdílet prostřednictvím


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]/@attrAvrá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. Proto instance 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říklad element(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á, ale processing-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 AtomicTypevyž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 aspř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>  
    

Viz také

výrazy XQuery
Typový systém (XQuery)