是否可以在列中操作xml?

时间:2017-03-09 20:31:53

标签: sql sql-server xml sql-server-2005

我有一张桌子:

create table foo (id int, reportDef xml)

reportDef包含一个长xml字符串。

<Report>
  <Criterias>
    <Criteria name="Date Range">...</Criteria>
    <Criteria name="Advertisers">
      <Elements>
        <Element name="CheckBoxOne">
          <Value>0</Value>
        </Element>
        <Element name="ListViewAvailable">
          <Value>314</Value>
          <Value>57</Value>
          <Value>18886</Value>
          <Value>7437</Value>
        </Element>
      </Elements>
    </Criteria>
    <Criteria name="Revenue Types">...</Criteria>
  </Criterias>
</Report>  

对于元素Criteria的name属性为“Advertisers”且元素Element的name属性为“ListViewAvailable”的情况,我想删除值为57和18886的Value元素。因此,在完成处理之后,XML应该看起来像这样:

<Report>
  <Criterias>
    <Criteria name="Date Range">...</Criteria>
    <Criteria name="Advertisers">
      <Elements>
        <Element name="CheckBoxOne">
          <Value>0</Value>
        </Element>
        <Element name="ListViewAvailable">
          <Value>314</Value>
          <Value>7437</Value>
        </Element>
      </Elements>
    </Criteria>
    <Criteria name="Revenue Types">...</Criteria>
  </Criterias>
</Report>  

这可能与SQL Server有关,尤其是2005版本吗?到目前为止,我得到了查询以提取可用值,但不知道在哪里继续操作和更新列。

SELECT C.value('.', 'varchar(100)'), t.id
FROM foo t
CROSS APPLY t.reportDef.nodes('
    /Report/Criterias/Criteria[@name="Advertisers"]
    /Elements/Element[@name="ListViewAvailable"]
    /Value
') Z(C)

1 个答案:

答案 0 :(得分:1)

这是你要找的吗?

DECLARE @foo TABLE(id INT,reportDef XML);
INSERT INTO @foo VALUES(1,
N'<Report>
  <Criterias>
    <Criteria name="Date Range">...</Criteria>
    <Criteria name="Advertisers">
      <Elements>
        <Element name="CheckBoxOne">
          <Value>0</Value>
        </Element>
        <Element name="ListViewAvailable">
          <Value>314</Value>
          <Value>57</Value>
          <Value>18886</Value>
          <Value>7437</Value>
        </Element>
      </Elements>
    </Criteria>
    <Criteria name="Revenue Types">...</Criteria>
  </Criterias>
</Report>');

SELECT * FROM @foo;

UPDATE @foo SET reportDef.modify(N'delete /Report/Criterias/Criteria[@name="Advertisers"]/Elements/Element[@name="ListViewAvailable"]/Value[text()="57" or text()="18886"]');

SELECT * FROM @foo;

我担心,这可能在2005年无效......目前无法检查......