SQL Server:在查询XML列时,我可以返回XML列吗?

时间:2012-10-26 13:21:41

标签: sql-server xml cursor

我有以下格式的XML:

<filters>
  <filter name="filterByOperatingSystem">
   <parameters operatingSystem="Windows" />
  </filter>
  <filter name="filterBySoftware">
   <parameter software="Office" />
  </filter>
</filters>

存储在@XML

我想做的是循环每个过滤器,以便我可以进行一些处理。

我的想法是我可以抓取每个过滤器名称以及游标中的参数元素,但到目前为止我能得到的最接近的是:

DECLARE crsDTO cursor static forward_only read_only for 
SELECT  
  tab.col.value('@name','NVARCHAR(64)')
FROM
  @XML.nodes('//filter') tab(col)

我尝试了以下查询以查看是否可以获取参数xml:

DECLARE crsDTO cursor static forward_only read_only for 
SELECT  
  tab.col.value('@name','NVARCHAR(64)'),
  tab.col.value('parameter[1]' 'XML')
FROM
  @XML.nodes('//filter') tab(col)

但是我得到了错误:

  

值类型中使用的数据类型XML无效

因为我的过滤器可以有不同的属性,我不想尝试直接使用第一个查询获取属性(我的想法是做光标,然后根据过滤器名称,我可以从节点获取特定参数),但是无法将xml节点取出,我不知道该怎么做。

有关如何解决这个问题的任何建议吗?

3 个答案:

答案 0 :(得分:3)

你需要这个吗?

DECLARE @XML xml = '<filters>
  <filter name="filterByOperatingSystem">
   <parameters operatingSystem="Windows" />
  </filter>
  <filter name="filterBySoftware">
   <parameter software="Office" />
  </filter>
</filters>'

SELECT  
  tab.col.value('@name','NVARCHAR(64)') as name,
  tab.col.query('./*') as parameters
FROM
  @XML.nodes('//filter') tab(col)

如果过滤器可能有其他子元素类型,则可能需要更改

  tab.col.query('./*') as parameters

  tab.col.query('./parameters') as parameters

  tab.col.query('./parameter') as parameters

什么是正确的名字。

答案 1 :(得分:2)

改为使用.query()

declare @xml xml = '<filters>
  <filter name="filterByOperatingSystem">
   <parameters operatingSystem="Windows" />
  </filter>
  <filter name="filterBySoftware">
   <parameter software="Office" />
  </filter>
</filters>';

SELECT  
  tab.col.value('@name','NVARCHAR(64)'),
  tab.col.query('.')
FROM
  @XML.nodes('//filter') tab(col)

答案 2 :(得分:1)

您的xml在Parameter个节点之一中没有Filter个元素,并且有Parameters个元素。因此,如果您想获取所有元素,则应编写*而不是parameter[1]

declare @xml xml

select @xml = '<filters>
  <filter name="filterByOperatingSystem">
   <parameters operatingSystem="Windows" />
  </filter>
  <filter name="filterBySoftware">
   <parameter software="Office" />
  </filter>
</filters>'

select @xml

select
    T.C.value('@name', 'nvarchar(64)'),
    T.C.query('./parameter[1]') as parameters
from @xml.nodes('/filters/filter') as T(C)