SQL 2008 データベースに次のような XML があり、XML フィールドに格納されています。ノードが XML の特定のセクションに存在するかどうかを true または false で示したいと思います。
<root>
<node attribute1='value1' attribute2='value2'>
<sub1 name='ID' value="1" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<entry attribute1='value1' attribute2='value2'>
<attribute name='project' value='done'>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="2" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="3" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="4" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<entry attribute1='value1' attribute2='value2'>
<attribute name='project' value='done'>
</entry>
</root>
お気づきのように、<attribute>
ノードは「ID」を持つノードの後に発生する場合と発生しない場合があります。この例では、適切な用語がないため、最初と 4 番目の「セクション」で確認できます。
次のテーブル構造を使用します。
ID (PK)
EventID (FK)
RawXML (XML)
Created (datetime)
以下は、これまでに入手した SQL/xQuery の抜粋です。
WITH XMLNAMESPACES(
'http://www.w3.org/2001/XMLSchema-instance' as xsi,
),
t1 as(
SELECT distinct
x.EventId
, c.value ('(//node/sub[@name=''ID'']/@value)[1]', 'nvarchar(max)') as ID
, c.value ('(//node/sub[@name=''ID''][1][descendant::attribute/@name=''project''])[1]', 'nvarchar(max)' ) as Exists
FROM
Table1 x
CROSS APPLY
RawXML.nodes('./.') as t(c)
)
select distinct
t1.ID
, t1.Exists
from t1
スクリプトを 4 回以上実行します (実行する前にすべてのシングルトン値を増やします)。
指定された XML について、クエリを 4 回実行した後、次の結果を得る必要があります (ID の値がわからないため、クエリで使用できません)。
ID Exists
---- -------
1 true
2 false
3 false
4 true
指定された SQL では、エラーは発生しませんでしたが、永遠に (45 分以上) かかり、まだ終了していません。XML を解析するのにこれほど長い時間はかからないはずです。
更新: クエリを制限して、1 行 (1 つの XML ファイル) のみを解析し、57 秒で終了したことを確認しました。ただし、ID 1 に「1」が必要な場合に、ID 1 と ID 2 に「0」という結果が得られました。
また、ほとんどの人は、次の兄弟などは SQL Server でサポートされていないため、残念ながらそれはオプションではないことを認識していると思います。
参考までに、これを使用して 'Project' の 2 つのインスタンスを見つけることができましたが、それらが発生する xml の場所は無視されます。
c.value ('(//node[descendant::attribute/@name=''Project''])[1]', 'nvarchar(max)' ) as TrueFalse
したがって、基本的には、name='ID' のノードの後に name='Project' のノードが存在するかどうかを知る必要がありますが、name='ID' のノードの次のインスタンスの前に存在するかどうかを知る必要があります。