私はXPathとXQueryに比較的慣れていません。と呼ばれるテーブルに格納されているXMLを使用していますtblXML
。XMLは、によってこのテーブルに格納されますcaseID
。この例では、この値は一意です。XML自体は、というラベルの付いた列に格納されますData
。
あなたが行った場合、あなたはselect * from tblXML where caseID = '12345'
これを見るでしょう:
caseID data
------ ------
12345 <root><patient><diagnosis preferred_name="diagnosis" tier="1">Melanoma</diagnosis> (XML file stored as blob in database)
XMLに飛び込むとすると、次のようになります。たとえば、これは「12345」のdata
列のXMLです。caseID
<root>
<patient>
<diagnosis preferred_name="diagnosis" tier="1">Melanoma</diagnosis>
<month_of_birth preferred_name="month_of_birth" tier="1">02</month_of_birth>
<day_of_birth preferred_name="day_of_birth" tier="2">01</day_of_birth>
<year_of_birth preferred_name="year_of_birth" tier="1">1960</year_of_birth>
<new_tumor_events>
<month_of_nte preferred_name="month_of_nte" tier="1">12</month_of_nte>
<day_of_nte preferred_name="day_of_nte" tier="2">30</day_of_nte>
<year_of_nte preferred_name="year_of_nte" tier="1">1994</year_of_nte>
</new_tumor_events>
<follow_ups>
<follow_up>
<month_of_fu preferred_name="month_of_fu" tier="1">12</month_of_fu>
<day_of_fu preferred_name="day_of_fu" tier="2">31</day_of_fu>
<year_of_fu preferred_name="year_of_fu" tier="1">1995</year_of_fu>
</follow_up>
<follow_up>
<month_of_fu preferred_name="month_of_fu" tier="1">12</month_of_fu>
<day_of_fu preferred_name="day_of_fu" tier="2">31</day_of_fu>
<year_of_fu preferred_name="year_of_fu" tier="1">1996</year_of_fu>
</follow_up>
</follow_ups>
</patient>
</root>
目標:@Tier
属性が。
であるXMLドキュメントのすべてのレベル/ノードのすべての要素のすべての値を選択しようとしています"1"
。次のように、「Value」という列の独自の行に各値が出力されるようにしたいと思います。
caseID Value
------ ------
12345 Melanoma
12345 02
12345 1960
12345 12
12345 1994
12345 12
12345 1995
12345 12
12345 1996
これが私が書き込もうとしているものに類似したSQLです:
DECLARE @tier int
SET @tier = '1' --To search by tier explicitly via variable
select
x.caseID,
bar.value('(//*[@tier = sql:variable("@tier")])[1]','varchar(max)') as value
from tblXML as x
CROSS APPLY data.nodes('//*:patient') AS foo(bar)
where
x.caseID = '12345'
and x.data.value('(//@tier)[1]', 'varchar(3)') = '1'
これは私に...
case ID value
------ ------
12345 Melanoma
...しかし、私が探している追加の行ではありません。
私の混乱は、[1]
CROSSAPPLYステートメントのシングルトンとコンテキストノードの両方によって課せられた制約に集中していると思います。クエリが検出したTier1の最初のインスタンスだけでなく、Tier1であるドキュメント内のすべてを取得する方法がわかりません。
この例では、CROSS APPLYステートメントのコンテキストノードがpatient
XMLのセクションに焦点を合わせていることを知っていますが、XMLツリーのすべてのレベルで上下両方を検索できるようにしたいと思います。//
forを使用すると、ドキュメントのすべてのレベルで検索できることはわかってい@Tier
ますが、コンテキストノードは、検索できるドキュメントの深さをある程度制限しているようです。
XMLを深く掘り下げて(follow_up
おそらく?)、上から下に検索できることを理解しています。ただし、最も深いノードはcaseIDからcaseIDに、XMLドキュメントからXMLドキュメントに変更されます。@Tier
CROSS APPLYステートメントを特定のXMLドキュメントの最も深いノードにワイルドカード化し、そのドキュメント内で出現するものを探して、対応する値を取得する方法はありますか?
私は、この方法が優雅さを欠き、パフォーマンスが悪いことを理解しています。これまでのところ、探している結果を提供するための明確なドキュメントを見つけることができませんでした。
よろしくお願いします。
編集:このSQLがSQLServerのテーブル値関数のコアになることを指定する必要があります。