【问题标题】:Replace value in XML using SQL使用 SQL 替换 XML 中的值
【发布时间】:2018-05-12 23:38:20
【问题描述】:

我需要使用 SQL 替换 xml 中的值,我面临的挑战是我要替换的值不在特定的 xpath 上,相同的值在不同的节点上,xpath 也不同,所以基本上我想要查找和替换一个值。

示例:

<data>
  <policy>
    <Effectivedate>2018-04-05</Effectivedate>
    <TermStartDate>2018-04-05</TermStartDate>
    <Line>
        <Risk>
            <Coverage>
                <Type>1</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>2</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>3</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
        </Risk>
    </Line>
  </policy>
 </data>

在上面的示例中,我需要将日期 2018-04-05 替换为 2018-04-06

任何人都可以在这里提供帮助。

【问题讨论】:

  • 什么数据库引擎?
  • 请为您正在使用的 RDBMS 添加一个标签,因为它们之间的字符串操作差异很大。另外,您能否在上面进行编辑以显示一些 XML 示例以及值必须如何更改?
  • 如果 XML 很简单,没有属性,也没有不规则的空格,这可能很容易。否则可能会很有挑战性。
  • 请分享您的数据实例,您尝试的代码。为什么你需要用 SQL 来做这件事?
  • 更新了一个例子

标签: sql-server xml tsql xpath xquery


【解决方案1】:

如果您必须替换不同路径中的元素,您可以将xml 转换为*char 并使用replace

declare @xml xml='<data> <policy> <Effectivedate>2018-04-05</Effectivedate> <TermStartDate>2018-04-05</TermStartDate> <Line> <Risk> <Coverage> <Type>1</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> <Coverage> <Type>2</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> <Coverage> <Type>3</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> </Risk> </Line> </policy> </data>'

select cast (replace (cast(@xml as nvarchar(max)), '2018-04-05','2018-04-06') as xml)

结果:

【讨论】:

    【解决方案2】:

    .modify() 函数不允许您在每次调用时更改多个值。您可以使用REPLACE() 在字符串级别执行此操作,但这可能会产生副作用...

    你可以做的(但这不会很快)是在循环中使用.modify(),直到所有出现的地方都被替换,像​​这样:

    DECLARE  @xml XML=
    N'<data>
      <policy>
        <Effectivedate>2018-04-05</Effectivedate>
        <TermStartDate>2018-04-05</TermStartDate>
        <Line>
            <Risk>
                <Coverage>
                    <Type>1</Type>
                    <coverstartdate>2018-04-05</coverstartdate>
                </Coverage>
                <Coverage>
                    <Type>2</Type>
                    <coverstartdate>2018-04-05</coverstartdate>
                </Coverage>
                <Coverage>
                    <Type>3</Type>
                    <coverstartdate>2018-04-05</coverstartdate>
                </Coverage>
            </Risk>
        </Line>
      </policy>
     </data>';
    
    WHILE @xml.exist(N'//*[text()="2018-04-05"]')=1
    BEGIN
        SET @xml.modify(N'replace value of (//*[text()="2018-04-05"]/text())[1] with "2018-04-06"');
    END
    SELECT @xml;
    

    这很丑陋(由于循环)而且很慢,但是 - 至少 - 它是 XQuery

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      • 2019-01-09
      • 1970-01-01
      相关资源
      最近更新 更多