階層に関係する XQuery
AdventureWorks データベースの大部分の xml 型の列は、部分的に構造化されたドキュメントです。 したがって、各行に格納されたドキュメントは異なって見える場合があります。 このトピックのクエリ サンプルでは、このようなさまざまなドキュメントから情報を抽出する方法について示します。
使用例
A. 製造命令ドキュメントから、ワーク センターの場所とその場所の最初の製造手順を取得
製品モデル 7 の場合、クエリは ProductModelID 属性と ProductModelName 属性が指定された <ManuInstr> 要素、およびその 1 つ以上の <Location> 子要素を含む XML を構築します。
各 <Location> 要素には、一連の独自の属性と 1 つの <step> 子要素があります。 この <step> 子要素は、そのワーク センターの場所での最初の製造手順です。
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
<ManuInstr ProdModelID = "{sql:column("Production.ProductModel.ProductModelID") }"
ProductModelName = "{ sql:column("Production.ProductModel.Name") }" >
{
for $wc in //AWMI:root/AWMI:Location
return
<Location>
{$wc/@* }
<step1> { string( ($wc//AWMI:step)[1] ) } </step1>
</Location>
}
</ManuInstr>
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7
上のクエリに関して、次の点に注意してください。
XQuery プロローグ内の namespace キーワードで、名前空間プレフィックスが定義されます。 このプレフィックスは、後からクエリ本文で使用されます。
XML 構築からクエリ評価にクエリを切り替えるために、コンテキスト切り替えトークンの {) と (} が使用されます。
構築される XML にリレーショナル値を含めるために、sql:column() が使用されます。
<Location> 要素を構築する際に、$wc/@* でそのワーク センターの場所のすべての属性が取得されます。
string() 関数は、<step> 要素から文字列値を返します。
結果の一部を次に示します。
<ManuInstr ProdModelID="7" ProductModelName="HL Touring Frame">
<Location LocationID="10" SetupHours="0.5"
MachineHours="3" LaborHours="2.5" LotSize="100">
<step1>Insert aluminum sheet MS-2341 into the T-85A
framing tool.</step1>
</Location>
<Location LocationID="20" SetupHours="0.15"
MachineHours="2" LaborHours="1.75" LotSize="1">
<step1>Assemble all frame components following
blueprint 1299.</step1>
</Location>
...
</ManuInstr>
B. AdditionalContactInfo 列のすべての電話番号の検索
次のクエリでは、<telephoneNumber> 要素の階層全体を検索することにより、特定の顧客の連絡先から追加の電話番号を取得します。 <telephoneNumber> 要素は階層内のどこにでも存在する可能性があるので、検索のクエリで子孫や自己演算子 (//) が使用されます。
SELECT AdditionalContactInfo.query('
declare namespace ci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
for $ph in /ci:AdditionalContactInfo//act:telephoneNumber
return
$ph/act:number
') as x
FROM Person.Contact
WHERE ContactID = 1
次に結果を示します。
<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
111-111-1111
</act:number>
<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
112-111-1111
</act:number>
最上位レベルの電話番号、具体的には <AdditionalContactInfo> の <telephoneNumber> 子要素だけを取得するには、クエリの FOR 式を次のように変更します。
for $ph in /ci:AdditionalContactInfo/act:telephoneNumber.