0

我有以下内容:

declare @xml XML

SET @xml = '<record priref="2" creation="2009-12-14T10:39:04">
      <field tag="aa" occ="1" lang="nl-NL">somedata</field>
      <field tag="bb" occ="1" lang="en-US">somedata</field>
      <field tag="bb" occ="2" lang="en-US">somedata</field>
      <field tag="cc" occ="1">testdata</field>
      <field tag="dd" occ="1">testdata</field>
      <field tag="ee" occ="1" lang="nl-NL">somedata</field>
      <field tag="ee" occ="1" lang="en-US">somedata</field>
    </record>' 

DECLARE @nodeCount int
DECLARE @i int

SET @i = 1

SELECT @nodeCount = @xml.value('count(/record/field/@lang)','varchar(5)') 

WHILE (@i <= @nodeCount)
BEGIN
Set @xml.modify('replace value of (/record/field/@lang)[.="en-US"][1] with "nl-NL"')

SET @i = @i + 1
END

SELECT @xml

我想有条件地更新属性@lang。

如果有一个节点具有相同的 'tag' 和 'occ' 属性值组合(如 tag=ee),@lang 的属性值必须保持不变。

在其他情况下,它必须像上面的查询一样进行更改:将“en-US”更改为“nl-NL”。

任何人都知道如何做到这一点?提前致谢!

4

1 回答 1

0

这应该这样做

DECLARE @xml XML;

SET @xml = '<record priref="2" creation="2009-12-14T10:39:04">
      <field tag="aa" occ="1" lang="nl-NL">somedata</field>
      <field tag="bb" occ="1" lang="en-US">somedata</field>
      <field tag="dd" occ="1">testdata</field>
      <field tag="bb" occ="2" lang="en-US">somedata</field>
      <field tag="cc" occ="1">testdata</field>
      <field tag="ee" occ="1" lang="nl-NL">somedata</field>
      <field tag="ee" occ="1" lang="en-US">somedata</field>
    </record>' 

DECLARE @no INT;
DECLARE @updneeded INT;
DECLARE nodecur CURSOR LOCAL FAST_FORWARD
FOR
  SELECT  rn,
          CASE WHEN COUNT(1) OVER ( PARTITION BY tag, occ ) > 1 THEN 0
               ELSE 1
          END updneeded
  FROM    ( SELECT  ROW_NUMBER() OVER ( ORDER BY node ) AS rn,
                    node.value('@tag', 'NVARCHAR(MAX)') AS tag,
                    node.value('@occ', 'NVARCHAR(MAX)') AS occ
            FROM    @xml.nodes('/record/field') x ( node )
          ) X;
OPEN nodecur;
WHILE ( 1 = 1 ) 
  BEGIN
    FETCH NEXT FROM nodecur INTO @no, @updneeded;
    IF ( @@FETCH_STATUS <> 0 ) BREAK;

    IF ( @updneeded = 1 ) 
      SET @xml.modify('replace value of (/record/field[sql:variable("@no")]/@lang)[.="en-US"][1] with "nl-NL"');
  END
CLOSE nodecur;
DEALLOCATE nodecur;

SELECT  @xml;

但是,对于这些类型的操作,SQL 的速度不是很快。在应用程序代码中执行此操作或将一些 CLR 函数放在一起可能更有效。

于 2012-10-18T00:23:38.043 回答