Dela via


Skriv castingregler i XQuery

gäller för:SQL Server

Följande specifikationer för W3C XQuery 1.0 och XPath 2.0 för funktioner och operatorer visar de inbyggda datatyperna. Detta inkluderar de inbyggda primitiva och inbyggda härledda typerna.

XQuery 1.0-typhierarki

I det här avsnittet beskrivs de typbegjutningsregler som tillämpas vid gjutning från en typ till en annan med någon av följande metoder:

  • Explicit gjutning som du gör med hjälp av cast som eller typkonstruktorfunktionerna (till exempel xs:integer("5")).

  • Implicit gjutning som inträffar under typhöjning

Explicit gjutning

I följande tabell beskrivs den tillåtna typgjutningen mellan de inbyggda primitiva typerna.

Beskriver gjutningsregler för XQuery.

  • En inbyggd primitiv typ kan omvandlas till en annan inbyggd primitiv typ, baserat på reglerna i tabellen.

  • En primitiv typ kan omvandlas till vilken typ som helst som härleds från den primitiva typen. Du kan till exempel casta från xs:decimal till xs:heltal, eller från xs:decimal till xs:long.

  • En härledd typ kan omvandlas till vilken typ som helst som är dess överordnade i typhierarkin, ända upp till den inbyggda primitiva bastypen. Du kan till exempel casta från xs:token till xs:normalizedString eller till xs:string.

  • En härledd typ kan omvandlas till en primitiv typ om dess primitiva överordnade kan omvandlas till måltypen. Du kan till exempel omvandla xs:heltal, en härledd typ, till en xs:string, primitiv typ, eftersom xs:decimal, xs:integer's primitiva överordnad, kan omvandlas till xs:string.

  • En härledd typ kan omvandlas till en annan härledd typ om källtypens primitiva överordnade kan omvandlas till måltypens primitiva överordnade. Du kan till exempel casta från xs:heltal till xs:token, eftersom du kan casta från xs:decimal till xs:string.

  • Reglerna för att casta användardefinierade typer till inbyggda typer är desamma som för de inbyggda typerna. Du kan till exempel definiera en myInteger typ härledd från xs:heltal typ. Sedan kan myInteger omvandlas till xs:tokeneftersom xs:decimal kan castas till xs:string.

Följande typer av gjutning stöds inte:

  • Det går inte att casta till eller från listtyper. Detta omfattar både användardefinierade listtyper och inbyggda listtyper som xs:IDREFS, xs:ENTITIESoch xs:NMTOKENS.

  • Det går inte att casta till eller från xs:QName.

  • xs:NOTATION och de fullständigt ordnade undertyperna av varaktighet stöds inte xdt:yearMonthDuration och xdt:dayTimeDuration. Därför stöds inte gjutning till eller från dessa typer.

Följande exempel illustrerar explicit typgjutning.

Exempel A

I följande exempel efterfrågas en xml-typvariabel. Frågan returnerar en sekvens av ett enkelt typvärde som skrivs som xs:string.

declare @x xml  
set @x = '<e>1</e><e>2</e>'  
select @x.query('/e[1] cast as xs:string?')  
go  

Exempel B

I följande exempel efterfrågas en typ av XML-variabel. Exemplet skapar först en XML-schemasamling. Den använder sedan XML-schemasamlingen för att skapa en typ av XML-variabel. Schemat innehåller skrivinformationen för XML-instansen som tilldelats variabeln. Frågor anges sedan mot variabeln.

create xml schema collection myCollection as N'  
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">  
      <xs:element name="root">  
            <xs:complexType>  
                  <xs:sequence>  
                        <xs:element name="A" type="xs:string"/>  
                        <xs:element name="B" type="xs:string"/>  
                        <xs:element name="C" type="xs:string"/>  
                  </xs:sequence>  
            </xs:complexType>  
      </xs:element>  
</xs:schema>'  
go  

Följande fråga returnerar ett statiskt fel eftersom du inte vet hur många <root> element på den översta nivån som finns i dokumentinstansen.

declare @x xml(myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
          <root><A>4</A><B>5</B><C>6</baz></C>'  
select @x.query('/root/A cast as xs:string?')  
go  

Genom att ange ett singleton-<root> element i uttrycket lyckas frågan. Frågan returnerar en sekvens av ett enkelt typvärde som skrivs som xs:string.

declare @x xml(myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
              <root><A>4</A><B>5</B><C>6</C></root>'  
select @x.query('/root[1]/A cast as xs:string?')  
go  

I följande exempel innehåller xml-typvariabeln ett dokumentnyckelord som anger XML-schemasamlingen. Detta anger att XML-instansen måste vara ett dokument som har ett enda element på den översta nivån. Om du skapar två <root> element i XML-instansen returneras ett fel.

declare @x xml(document myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
              <root><A>4</A><B>5</B><C>6</C></root>'  
go  

Du kan ändra instansen så att den endast innehåller ett element på den översta nivån och frågan fungerar. Återigen returnerar frågan en sekvens av ett enkelt typvärde som skrivs som xs:string.

declare @x xml(document myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>'  
select @x.query('/root/A cast as xs:string?')  
go  

Implicit gjutning

Implicit gjutning tillåts endast för numeriska typer och otypade atomiska typer. Följande min()-funktionen returnerar till exempel minst de två värdena:

min(xs:integer("1"), xs:double("1.1"))  

I det här exemplet är de två värden som skickas till funktionen XQuery min() av olika typer. Därför utförs implicit konvertering där heltal typ befordras till dubbla och de två dubbla värdena jämförs.

Typhöjningen enligt beskrivningen i det här exemplet följer dessa regler:

  • En inbyggd härledd numerisk typ kan höjas upp till bastypen. Till exempel kan heltal höjas till decimal.

  • En decimal kan höjas till flyttal, och en flyttal kan höjas upp till dubbla.

Eftersom implicit gjutning endast tillåts för numeriska typer tillåts inte följande:

  • Implicit gjutning för strängtyper tillåts inte. Om till exempel två sträng typer förväntas och du skickar in en sträng och en token, sker ingen implicit gjutning och ett fel returneras.

  • Implicit gjutning från numeriska typer till strängtyper tillåts inte. Om du till exempel skickar ett heltalstypvärde till en funktion som förväntar sig en strängtypsparameter inträffar ingen implicit gjutning och ett fel returneras.

Gjutningsvärden

När du gjuter från en typ till en annan omvandlas de faktiska värdena från källtypens värdeutrymme till måltypens värdeutrymme. Om du till exempel genererar från en xs:decimal till en xs:double omvandlas decimalvärdet till ett dubbelt värde.

Följande är några av transformeringsreglerna.

Gjuta ett värde från en sträng eller otypedAtomic-typ

Värdet som omvandlas till en sträng eller otypedAtomic-typ transformeras på samma sätt som värdet verifieras baserat på måltypens regler. Detta omfattar eventuella mönster och regler för bearbetning av tomt utrymme. Följande lyckas till exempel och genererar ett dubbelt värde, 1.1e0:

xs:double("1.1")

Vid gjutning till binära typer som xs:base64Binary eller xs:hexBinary från en sträng eller otypedAtomic-typ måste indatavärdena vara base64 respektive hexkodade.

Gjuta ett värde till en sträng eller otypedAtomic-typ

Om du omvandlar till en sträng eller en otypedAtomic-typ transformeras värdet till dess XQuery-kanoniska lexikala representation. Mer specifikt kan detta innebära att ett värde som kan ha följt ett specifikt mönster eller annan begränsning under indata inte representeras enligt den begränsningen. För att informera användarna om detta skriver SQL Server-flaggor där typbegränsningen kan vara ett problem genom att ge en varning när dessa typer läses in i schemasamlingen.

När du gjuter ett värde av typen xs:float eller xs:double, eller någon av deras undertyper, till en sträng eller otypedAtomic-typ, representeras värdet i vetenskaplig notation. Detta görs bara när värdets absoluta värde är mindre än 1,0E-6, eller större än eller lika med 1,0E6. Det innebär att 0 serialiseras i vetenskaplig notation till 0.0E0.

Till exempel returnerar xs:string(1.11e1) strängvärdet "11.1", medan xs:string(-0.00000000002e0) returnerar strängvärdet "-2.0E-11".

Vid gjutning av binära typer, till exempel xs:base64Binary eller xs:hexBinary, till en sträng eller otypedAtomic-typ, representeras de binära värdena i deras base64- eller hexkodade formulär.

Gjuta ett värde till en numerisk typ

När du gjuter ett värde av en numerisk typ till ett värde av en annan numerisk typ mappas värdet från ett värdeutrymme till ett annat utan att gå igenom sträng serialisering. Om värdet inte uppfyller villkoret för en måltyp gäller följande regler:

  • Om källvärdet redan är numeriskt och måltypen antingen är xs:float eller en undertyp som tillåter -INF- eller INF-värden, och gjutning av det numeriska källvärdet skulle resultera i ett spill, mappas värdet till INF om värdet är positivt eller -INF om värdet är negativt. Om måltypen inte tillåter INF eller -INF, och ett spill skulle inträffa, misslyckas casten och resultatet i den här versionen av SQL Server är den tomma sekvensen.

  • Om källvärdet redan är numeriskt och måltypen är en numerisk typ som innehåller 0, -0e0 eller 0e0 i dess godkända värdeintervall, och gjutning av det numeriska källvärdet skulle resultera i ett underflöde, mappas värdet på följande sätt:

    • Värdet mappas till 0 för en decimalmåltyp.

    • Värdet mappas till -0e0 när värdet är ett negativt underflöde.

    • Värdet mappas till 0e0 när värdet är ett positivt underflöde för en flyttal eller dubbel måltyp.

    Om måltypen inte innehåller noll i dess värdeutrymme misslyckas gjutningen och resultatet är den tomma sekvensen.

    Observera att gjutning av ett värde till en binär flyttalstyp, till exempel xs:float, xs:double eller någon av deras undertyper, kan förlora precision.

Implementeringsbegränsningar

Det här är begränsningarna:

  • Flyttalsvärdet NaN stöds inte.

  • Kastreringsbara värden begränsas av implementeringsbegränsningarna för måltyper. Du kan till exempel inte omvandla en datumsträng med ett negativt år för att xs:date. Sådana avbildningar resulterar i den tomma sekvensen om värdet anges vid körning (i stället för att generera ett körningsfel).

Se även

Definiera serialisering av XML-data