6

SQL Server 2008を使用していて、XML要素を取得して、サブ要素やtext()なしで要素自体とその属性を返したいと考えています。たとえば、次のXMLには4つのノード(doc、apple、b、banana)があります。

<doc>
<apple type="bramley"> tasty <b>yum!</b> </apple>
<banana color="yellow" shape="bendy"> nice in smoothies </banana>
</doc>

戻りたい:

<doc/>
<apple type="bramley"/>
<b/>
<banana color="yellow" shape="bendy"/>

たとえば、 docはサブノードなしで返され、appleはbサブノードなしで返される必要があります。ただし、問題は、SQL Serverノードとクエリメソッドを使用すると、サブノードを削除できないことです。SQL Server 2008を使用すると、最も近いものは次のとおりです。

declare @x xml = '<doc>
  <apple type="bramley"> tasty <b>yum!</b> </apple>
  <banana color="yellow" shape="bendy"> nice in smoothies </banana>
</doc>';

select 
  c.query('local-name(.)') as Node,
  c.query('for $e in . return <xx> {$e/@*} </xx>') as Attr
from @x.nodes('//*') as T(c);

これにより、各ノードの名前(local-nameを使用)とノードの属性が取得され、次の値が返されます。

Node    Attr
----    ----
doc     <xx />
apple   <xx type="bramley" />
b       <xx />
banana  <xx color="yellow" shape="bendy" />

この結果を処理し、Attrをvarcharに変換し、xxをNode列に置き換えて、XMLに戻すことができることに気付きました。しかし、文字列操作なしでもっと簡単な方法はありますか?

PS:それが役に立ったら、ソリューションがSQLServer2008とSQLServer2012のどちらを使用してもかまいません。

4

1 に答える 1

1

通常、動的タグ名で要素の構築を使用しますが、SQLServerはこれをサポートしていません。

declare @x xml = '<doc>
  <apple type="bramley"> tasty <b>yum!</b> </apple>
  <banana color="yellow" shape="bendy"> nice in smoothies </banana>
</doc>';

select 
  c.query('local-name(.)') as Node,
  c.query('for $e in . return element { local-name($e) } { $e/@* } </xx>') as Attr
from @x.nodes('//*') as T(c);

XQuery Updateの代替手段(SQL Server 2012でテスト済み)として、すべてのノード(すべてのコンテンツを含む)をフェッチし、それらのサブノートを削除できます。

DECLARE @x xml = '<doc>test
  <apple type="bramley"> tasty <b>yum!</b> </apple>
  <banana color="yellow" shape="bendy"> nice in smoothies </banana>
</doc>';

-- Fetch all nodes
SET @x = @x.query('//*')
-- Delete all subnodes
SET @x.modify('delete /*/node()')

select 
  c.query('.') as NewNode
from @x.nodes('/*') as T(c);
于 2012-12-16T23:40:50.943 に答える