SQL Server 2008查询中的XML数据类型

时间:2012-03-14 18:46:52

标签: sql xml sql-server-2008

我在SQL Server中有一个表,其中一列是XML数据类型。表中还有其他列不是XML。以下是存储在列中的XML示例:

<AdultAsthma>
  <Group>
    <Question text="Act Score:" ForeColor="Green" />
    <Controls>
      <Control type="Label" id="txtScore" text="Enter ACT Score:" ForeColor="Black" />
      <Control type="TextBox" id="txtActScore" Answer="" />
    </Controls>
  </Group>
</AdultAsthma>

我想要的是一个匹配表中其他列的某些值的查询,对于那些匹配的列,我想从问题节点获取text属性,从Control节点获取Answer属性。有人可以帮我这个吗?

修改

如果我有多个Group节点,需要更改什么?在这个场景中,我希望每个问题的文本和答案都与每个问题一致。见下文:

<AdultAsthma>
  <Group>
    <Question text="Act Score:" ForeColor="Green" />
    <Controls>
      <Control type="Label" id="txtScore" text="Enter ACT Score:" ForeColor="Black" />
      <Control type="TextBox" id="txtActScore" Answer="" />
    </Controls>
  </Group>
  <Group>
    <Question text="Do You Have Asthma?:" ForeColor="Black" />
    <Controls>
      <Control type="RadioButton" id="rbHaveAsthmaYes" text="Yes" GroupName="Diagnosed" ForeColor="Black" Answer="False" />
      <Control type="RadioButton" id="rbHaveAsthmaNo" text="No" GroupName="Diagnosed" ForeColor="Black" Answer="False" />
    </Controls>
  </Group>
</AdultAsthma>

1 个答案:

答案 0 :(得分:6)

declare @T table
(
  XMLCol xml
)

insert into @T values
('<AdultAsthma>
  <Group>
    <Question text="Act Score:" ForeColor="Green" />
    <Controls>
      <Control type="Label" id="txtScore" text="Enter ACT Score:" ForeColor="Black"/>
      <Control type="TextBox" id="txtActScore" Answer="Answer" />
    </Controls>
  </Group>
</AdultAsthma>
')

select XMLCol.value(N'(/AdultAsthma/Group/Question/@text)[1]', 'nvarchar(max)'),
       XMLCol.value(N'(/AdultAsthma/Group/Controls/Control/@Answer)[1]', 'nvarchar(max)')
from @T

更新

当您需要将XML分解为多行时,可以在.nodes()中使用cross apply

declare @T table
(
  XMLCol xml
)

insert into @T values
('<AdultAsthma>
  <Group>
    <Question text="Act Score:" ForeColor="Green" />
    <Controls>
      <Control type="Label" id="txtScore" text="Enter ACT Score:" ForeColor="Black" />
      <Control type="TextBox" id="txtActScore" Answer="" />
    </Controls>
  </Group>
  <Group>
    <Question text="Do You Have Asthma?:" ForeColor="Black" />
    <Controls>
      <Control type="RadioButton" id="rbHaveAsthmaYes" text="Yes" GroupName="Diagnosed" ForeColor="Black" Answer="False" />
      <Control type="RadioButton" id="rbHaveAsthmaNo" text="No" GroupName="Diagnosed" ForeColor="Black" Answer="False" />
    </Controls>
  </Group>
</AdultAsthma>
')

select X.N.value(N'(Question/@text)[1]', 'nvarchar(max)'),
       X.N.value(N'(Controls/Control/@Answer)[1]', 'nvarchar(max)')
from @T as T
  cross apply T.XMLCol.nodes(N'/AdultAsthma/Group') as X(N)