SequenceType 式 (XQuery)
適用対象: SQL Server
XQuery では、値は常にシーケンスです。 値の型はシーケンス型と呼ばれます。 シーケンス型は、XQuery 式ので使用できます。 XQuery 式で型を参照する必要があるときは、XQuery 仕様に記載されている SequenceType 構文を使用します。
アトミック型名は、 キャスト as XQuery 式でも使用できます。 SQL Server では、SequenceTypes での XQuery 式のとキャストが部分的にサポートされています。
Operator のインスタンス
演算子を使用して、指定した式の値の動的な型 (実行時) を決定できます。 次に例を示します。
Expression instance of SequenceType[Occurrence indicator]
instance of
演算子 (Occurrence indicator
) は、カーディナリティ、結果のシーケンス内の項目数を指定します。 これが指定されていない場合、カーディナリティは 1 と見なされます。 SQL Server では、疑問符 (?) 発生インジケーターのみがサポートされています。 ?発生インジケーターは、Expression
が 0 個または 1 つの項目を返すことができることを示します。 ?発生インジケーターが指定されている場合、instance of
は、Expression
型が指定したSequenceType
と一致する場合、Expression
がシングルトンまたは空のシーケンスを返すかどうかに関係なく True を返します。
?発生インジケーターが指定されていない場合、sequence of
は true を返します。Expression
型が指定されたType
と一致し、Expression
がシングルトンを返す場合のみです。
注 SQL Server では、プラス記号 (+) とアスタリスク (*) の発生インジケーターはサポートされていません。
次の例は、XQuery 演算子のinstance の使用を示しています。
例 A
次の例では、 xml 型変数を作成し、それに対するクエリを指定します。 クエリ式は、最初のオペランドによって返される値の動的な型が、2 番目のオペランドで指定された型と一致するかどうかを判断する instance of
演算子を指定します。
次のクエリは True を返します。125 の値は、指定した型 xs:integerのインスタンスであるためです。
declare @x xml
set @x=''
select @x.query('125 instance of xs:integer')
go
次のクエリでは、最初のオペランドの式 /a[1] から返される値が要素なので True が返されます。
declare @x xml
set @x='<a>1</a>'
select @x.query('/a[1] instance of element()')
go
同様に、次のクエリでは最初の式に含まれている式の値の型が属性型なので、instance of
から True が返されます。
declare @x xml
set @x='<a attr1="x">1</a>'
select @x.query('/a[1]/@attr1 instance of attribute()')
go
次の例では、式 data(/a[1]
は、xdt:untypedAtomic として型指定されたアトミック値を返します。 したがって、 instance of
は True を返します。
declare @x xml
set @x='<a>1</a>'
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')
go
次のクエリでは、式 data(/a[1]/@attrA
は型指定されていないアトミック値を返します。 したがって、 instance of
は True を返します。
declare @x xml
set @x='<a attrA="X">1</a>'
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')
go
例 B
この例では、AdventureWorks サンプル データベースの型指定された XML 列に対してクエリを実行しています。 クエリ対象の列に関連付けられている XML スキーマ コレクションは、入力情報を提供します。
式では、 data() は、列に関連付けられているスキーマに従って、型が xs:string である ProductModelID 属性の型指定された値を返します。 したがって、 instance of
は 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
詳細については、「 型指定された XML と型指定されていない XML の比較」を参照してください。
次のクエリでは、ブール instance of
式を使用して、LocationID 属性が 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
CatalogDescription 型の XML 列に対して、次のクエリを指定します。 この列に関連付けられた XML スキーマ コレクションにより、型指定情報が提供されます。
クエリでは、instance of
式のelement(ElementName, ElementType?)
テストを使用して、/PD:ProductDescription[1]
が特定の名前と型の要素ノードを返すかどうかを確認します。
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
クエリは True を返します。
例 C
共用体型を使用する場合、SQL Server の instance of
式には制限があります。具体的には、要素または属性の型が共用体型の場合、 instance of
は正確な型を決定できない可能性があります。 したがって、SequenceType で使用されているアトミック型が、simpleType 階層内にある式の実際の型の最上位の親でない限り、クエリから False が返されます。 つまり、SequenceType で指定されるアトミック型は、anySimpleType の直接の子である必要があります。 型階層の詳細については、「XQuery の 型キャストルールを参照してください。
次のクエリ例では、次の処理を実行します。
整数型や文字列型などの共用体型が定義された XML スキーマ コレクションを作成します。
XML スキーマ コレクションを使用して、型指定された xml 変数を宣言します。
サンプル XML インスタンスを変数に割り当てます。
変数にクエリして、共用体型を処理するときの
instance of
の動作を示します。
クエリは次のとおりです。
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
次のクエリでは、instance of
式に指定している SequenceType が、指定した式の実際の型の最上位の親ではないので False が返されます。 つまり、 <TestElement
> の値は整数型です。 最上位の親は xs:decimal です。 しかし、この型が instance of
演算子の 2 つ目のオペランドとして指定されていません。
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
xs:integer の最上位の親は xs:decimal であるため、クエリを変更し、クエリで SequenceType として xs:decimal を指定すると、クエリは True を返します。
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
例 D
この例では、最初に XML スキーマ コレクションを作成し、それを使用して xml 変数を入力します。 その後、型指定された xml 変数が照会され、 instance of
機能が示されます。
次の XML スキーマ コレクションは、myType 型の単純型、myType、および要素 ( <root
>) を定義します。
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
次に、型指定された xml 変数を作成し、クエリを実行します。
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
myType 型は、sqltypes スキーマで定義されている varchar 型から制限によって派生するため、 instance of
は 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
例 E
次の例では、式で IDREFS 属性のいずれかの値を取得し、instance of
を使用して値が IDREF 型かどうかを判断しています。 この例では、次の処理を実行します。
<
Customer
>要素が OrderList IDREFS 型属性を持ち、<Order
> 要素が OrderID ID 型属性を持つ XML スキーマ コレクションを作成します。型指定された xml 変数を作成し、それにサンプル XML インスタンスを割り当てます。
変数に対してクエリを指定します。 クエリ式は、最初の <
Customer
>の OrderList IDRERS 型属性から最初の注文 ID 値を取得します。 取得される値は IDREF 型です。 したがって、instance of
は 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
実装の制限事項
制限事項は次のとおりです。
schema-element()およびschema-attribute()シーケンス型は、
instance of
演算子との比較ではサポートされていません。完全なシーケンス (
(1,2) instance of xs:integer*
など) はサポートされていません。element(ElementName, TypeName)
などの型名を指定する element() シーケンス型の形式を使用する場合、その型は疑問符 (?) で修飾する必要があります。 たとえば、element(Title, xs:string?)
は要素が NULL であることを示します。 SQL Server では、instance of
を使用した xsi:nil プロパティの実行時検出はサポートされていません。Expression
の値が共用体として型指定された要素または属性から取得される場合、SQL Server は、値の型の派生元のプリミティブ型 (派生型ではなく) のみを識別できます。 たとえば、静的な型 (xs:integer | xs:string) を持つ <e1
> が定義されている場合、次は False を返します。data(<e1>123</e1>) instance of xs:integer
ただし、
data(<e1>123</e1>) instance of xs:decimal
は True を返します。processing-instruction()およびdocument-node()シーケンス型の場合、引数のないフォームのみが許可されます。 たとえば、
processing-instruction()
は使用できますが、processing-instruction('abc')
は使用できません。
演算子としてキャスト
キャスト as 式を使用して、値を特定のデータ型に変換できます。 次に例を示します。
Expression cast as AtomicType?
SQL Server では、 AtomicType
の後に疑問符 (?) が必要です。 たとえば、次のクエリに示すように、 "2" cast as xs:integer?
は文字列値を整数に変換します。
declare @x xml
set @x=''
select @x.query('"2" cast as xs:integer?')
次のクエリでは、 data() は ProductModelID 属性の型指定された値 (文字列型) を返します。 cast as
operator は、値を 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
このクエリでは、 data() を明示的に使用する必要はありません。 cast as
式は、入力式に対して暗黙的なアトミック化を実行します。
コンストラクター関数
アトミック型コンストラクター関数を使用できます。 たとえば、 cast as
演算子を使用する代わりに、 "2" cast as xs:integer?
、次の例のように、 xs:integer() コンストラクター関数を使用できます。
declare @x xml
set @x=''
select @x.query('xs:integer("2")')
次の例では、2000-01-01Z に等しい xs:date 型の値が返されます。
declare @x xml
set @x=''
select @x.query('xs:date("2000-01-01Z")')
また、ユーザー定義のアトミック型にコンストラクターを使用することもできます。 たとえば、XML データ型に関連付けられている XML スキーマ コレクションで単純型が定義されている場合、 myType() コンストラクターを使用してその型の値を返すことができます。
実装の制限事項
XQuery 式 typeswitch、 castable、 treat はサポートされていません。
cast as には、アトミック型の後に疑問符 (?) が必要です。
xs:QName はキャストの型としてサポートされていません。 代わりに expanded-QName を使用してください。
xs:date、 xs:time、および xs:datetime には、Z で示されるタイム ゾーンが必要です。
タイム ゾーンが指定されていないため、次のクエリは失敗します。
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>') go
Z タイム ゾーン インジケーターを値に追加すると、クエリが機能します。
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>') go
結果を次に示します。
<a>2002-05-25Z</a>