Sdílet prostřednictvím


XQuery a statické psaní

platí pro:SQL Server

XQuery v SQL Serveru je staticky napsaný jazyk. To znamená, že vyvolá chyby typu během kompilace dotazu, když výraz vrátí hodnotu, která má typ nebo kardinalitu, která není přijata konkrétní funkcí nebo operátorem. Kromě toho může statická kontrola typů zjistit, jestli byl výraz cesty v zadaném dokumentu XML chybný. Kompilátor XQuery nejprve použije fázi normalizace, která přidá implicitní operace, jako je atomizace, a pak provede kontrolu odvození statického typu a statického typu.

Odvození statického typu

Odvození statického typu určuje návratový typ výrazu. Určuje to tak, že vezme statické typy vstupních parametrů a statickou sémantiku operace a odvodí statický typ výsledku. Například statický typ výrazu 1 + 2,3 je určen následujícím způsobem:

  • Statický typ 1 je xs:integer a statický typ 2,3 je xs:decimal. Na základě dynamické sémantiky statická sémantika operace + převede celé číslo na desetinné číslo a vrátí desítkové číslo. Odvozený statický typ by pak byl xs:decimal.

U netypových instancí XML existují speciální typy, které označují, že data nebyla zadána. Tyto informace se používají při kontrole statického typu a k provádění určitých implicitních přetypování).

U zadaných dat je vstupní typ odvozen z kolekce schémat XML, která omezuje instanci datového typu XML. Pokud například schéma umožňuje pouze prvky typu xs:integer, výsledky výrazu cesty používajícího tento prvek budou nula nebo více prvků typu xs:integer. Tento výraz se v současné době vyjadřuje pomocí výrazu, například element(age,xs:integer)*, kde hvězdička (*) označuje kardinalitu výsledného typu. V tomto příkladu může výsledkem výrazu být nula nebo více prvků názvu "age" a typ xs:integer. Jiné kardinality jsou přesně jedna a jsou vyjádřeny pomocí samotného názvu typu, nuly nebo jedné a vyjádřené pomocí otazníku (?) a 1 nebo více a vyjádřeno pomocí znaménka plus (+).

Někdy může odvození statického typu odvodit, že výraz vždy vrátí prázdnou sekvenci. Pokud například výraz cesty u zadaného datového typu XML hledá prvek <název> uvnitř elementu <customer> (/customer/name), ale schéma neumožňuje <název> uvnitř <zákazníka>, odvození statického typu odvodí, že výsledek bude prázdný. Použije se k detekci nesprávných dotazů a bude hlášena jako statická chyba, pokud výraz nebyl () nebo data( () ).

Podrobná pravidla odvozování jsou poskytována ve formální sémantice specifikace XQuery. Společnost Microsoft tyto instance datových typů XML změnila jen mírně tak, aby fungovala pouze s instancemi datových typů XML. Nejdůležitější změnou ze standardu je, že implicitní uzel dokumentu zná typ instance datového typu XML. Výsledkem je, že výraz cesty formuláře /age bude přesně zadaný na základě těchto informací.

Pomocí šablon a oprávnění sql Serveru Profilermůžete zobrazit statické typy vrácené jako součást kompilací dotazů. Abyste je viděli, musí trasování obsahovat událost statického typu XQuery do kategorie událostí TSQL.

Statická kontrola typů

Statická kontrola typů zajišťuje, že provádění za běhu bude přijímat pouze hodnoty, které jsou vhodným typem operace. Vzhledem k tomu, že typy nemusí být kontrolovány za běhu, mohou být zjištěny potenciální chyby v rané fázi kompilace. To pomáhá zlepšit výkon. Statické psaní ale vyžaduje, aby zapisovač dotazů byl při formulaci dotazu opatrnější.

Níže jsou uvedené vhodné typy, které je možné použít:

  • Typy explicitně povolené funkcí nebo operací

  • Podtyp explicitně povoleného typu.

Podtypy jsou definovány na základě pravidel podtypů pro použití odvození omezením nebo rozšířením schématu XML. Například typ S je podtyp typu T, pokud všechny hodnoty, které mají typ S, jsou také instance typu T.

Kromě toho jsou všechny celočíselné hodnoty také desetinné hodnoty založené na hierarchii typů schématu XML. Ne všechny desetinné hodnoty jsou ale celá čísla. Celé číslo je tedy podtyp desetinných míst, ale ne naopak. Operace + například umožňuje pouze hodnoty určitých typů, například číselné typy xs:integer, xs:decimal, xs:floata xs:double. Pokud jsou předány hodnoty jiných typů, například xs:string, vyvolá operace chybu typu. To se označuje jako silné psaní. Hodnoty jiných typů, například atomický typ použitý k označení netypového XML, lze implicitně převést na hodnotu typu, který operace přijímá. Označuje se jako slabé psaní.

Pokud je požadován po implicitním převodu, statická kontrola typů zaručuje, že operaci předají pouze hodnoty povolených typů se správnou kardinalitou. U řetězce + 1 rozpozná, že statický typ "string" je xs:string. Vzhledem k tomu, že tento typ není povolený pro operaci +, vyvolá se chyba typu.

V případě přidání výsledku libovolného výrazu E1 do libovolného výrazu E2 (E1 + E2) nejprve určí odvození statického typu E1 a E2 statické typy a pak zkontroluje jejich statické typy s povolenými typy operace. Pokud může být například statický typ E1 xs:string nebo xs:integer, vyvolá kontrola statického typu chybu typu, i když některé hodnoty za běhu můžou být celá čísla. Totéž by bylo v případě, že statický typ E1 byl xs:integer*. Vzhledem k tomu, že operace + přijímá pouze jednu celočíselnou hodnotu a E1 může vrátit nulu nebo více než 1, vyvolá kontrola statického typu chybu.

Jak už bylo zmíněno dříve, odvození typu často odvodí typ, který je širší než to, co uživatel ví o typu předávaných dat. V těchto případech musí uživatel dotaz přepsat. Mezi typické případy patří:

  • Typ odvodí obecnější typ, jako je supertyp nebo sjednocení typů. Pokud je typ atomický typ, měli byste použít funkci přetypování nebo konstruktoru k označení skutečného statického typu. Pokud je například odvozený typ výrazu E1 volbou mezi xs:string nebo xs:integer a sčítání vyžaduje xs:integer, měli byste místo E1+E2psát xs:integer(E1) + E2 . Tento výraz může v době běhu selhat, pokud je zjištěna hodnota řetězce, která nelze přetypovat na xs:integer. Výraz ale nyní předá kontrolu statického typu. Tento výraz je namapován na prázdnou sekvenci.

  • Typ odvodí vyšší kardinalitu, než jaká data skutečně obsahují. K tomu dochází často, protože datový typ xml může obsahovat více než jeden prvek nejvyšší úrovně a kolekce schémat XML nemůže toto omezení omezit. Chcete-li snížit statický typ a zaručit, že existuje skutečně maximálně jedna hodnota, měli byste použít poziční predikát [1]. Pokud například chcete přidat hodnotu 1 k hodnotě atributu c prvku b pod prvek nejvyšší úrovně, musíte write (/a/b/@c)[1]+1. Kromě toho lze klíčové slovo DOCUMENT použít společně s kolekcí schémat XML.

  • Některé operace při odvození ztratí informace o typu. Pokud například nelze určit typ uzlu, stane se anyType. Toto není implicitně přetypování na žádný jiný typ. Tyto převody se nejčastěji vyskytují při navigaci pomocí nadřazené osy. Pokud výraz vytvoří chybu statického typu, měli byste se těmto operacím vyhnout a dotaz přepsat.

Kontrola typů sjednocení

Typy sjednocení vyžadují pečlivé zpracování kvůli kontrole typů. Dva z těchto problémů jsou znázorněny v následujících příkladech.

Příklad: Funkce nad typem sjednocení

Zvažte definici elementu pro <r> sjednocovacího typu:

<xs:element name="r">  
<xs:simpleType>  
   <xs:union memberTypes="xs:int xs:float xs:double"/>  
</xs:simpleType>  
</xs:element>  

V kontextu XQuery vrátí funkce průměr fn:avg (//r) statickou chybu, protože kompilátor XQuery nemůže přidat hodnoty různých typů (xs:int, xs:float nebo xs:double) pro <r> elementy v argumentu fn:avg(). Chcete-li tento problém vyřešit, přepište vyvolání funkce jako fn:avg(for $r in //r return $r cast as xs:double ?).

Příklad: Operátor nad typem sjednocení

Operace sčítání (+) vyžaduje přesné typy operandů. Výsledkem je, že výraz (//r)[1] + 1 vrátí statickou chybu, která má dříve popsanou definici typu pro prvek <r>. Jedním z řešení je přepsat ho jako (//r)[1] cast as xs:int? +1, kde "?" označuje 0 nebo 1 výskyty. SQL Server vyžaduje přetypování jako s "?", protože jakékoli přetypování může způsobit prázdnou sekvenci v důsledku chyb za běhu.

Viz také

jazyka XQuery (SQL Server)