【问题标题】:Updating the xml data nodes by passing the SQL variable通过传递 SQL 变量更新 xml 数据节点
【发布时间】:2019-08-15 15:56:47
【问题描述】:

我有以下XML,我需要根据参数更新指定的:

<DOPremium>
    <BasePremium>337500</BasePremium>
    <TotalPremium>337500</TotalPremium>
    <NettPremium>337500</NettPremium>
    <GrossPremium>337500</GrossPremium>
    <OptionId>0</OptionId>
</DOPremium>
<DOPremium>
     <BasePremium>337500</BasePremium>
     <TotalPremium>337500</TotalPremium>
     <NettPremium>337500</NettPremium>
     <GrossPremium>337500</GrossPremium>
     <OptionId>1</OptionId>
</DOPremium>
<DOPremium>
     <BasePremium>337500</BasePremium>
     <TotalPremium>337500</TotalPremium>
     <NettPremium>337500</NettPremium>
     <GrossPremium>337500</GrossPremium>
     <OptionId>2</OptionId>
</DOPremium>

我正在尝试根据DOPremium 对象的选择更新相应的节点,但我无法做到这一点。有人可以验证我错在哪里吗?

SET @NewXmlValue = N' <BasePremium>[sql:variable("@R15_premium")]</BasePremium>'
SET @DataXml.modify('delete /*/Premiums/DOPremium/BasePremium[sql:variable("@OptionID")]')          
SET @DataXml.modify('insert sql:variable("@NewXmlValue") into (/*/Premiums/DOPremium[sql:variable("@OptionID")])[1]')           

-- Add TotalPremium
SET @NewXmlValue = N' <TotalPremium>[sql:variable("@R15_premium")]</TotalPremium>'
SET @DataXml.modify('delete /*/Premiums/DOPremium/TotalPremium[sql:variable("@OptionID")]')         
SET @DataXml.modify('insert sql:variable("@NewXmlValue") into (/*/Premiums/DOPremium[sql:variable("@OptionID")])[1]')

【问题讨论】:

    标签: sql-server xml nodes


    【解决方案1】:

    好的,首先,这行不通:

    SET @NewXmlValue = N'<BasePremium>[sql:variable("@R15_premium")]</BasePremium>'
    

    sql:variable() 仅被解释为 XQuery 操作中的函数。这不是 XQuery 操作,因此它只会以文本形式插入 sql:variable(...)。如果你想要一个带有变量文本值的实际 XML 节点,你必须更迂回一些:

    SET @NewXmlValue = '';
    SET @NewXmlValue = (SELECT @NewXmlValue.query('<BasePremium>{sql:variable("@R15_premium")}</BasePremium>'));
    

    这种方法(和其他方法)可以在docs 中找到。 (在这个非常简单的情况下,在 T-SQL 中连接字符串当然也可以,但总的来说这不是一个好主意,因为它不会在必要时转义 XML。)

    用于选择所需DOPremium 节点的语法也需要修改——/BasePremium[sql:variable("@OptionID")] 是合法的,但它的意思是“BasePremium 节点,从 1 开始,编号为 @OptionID”。如果@OptionID 应该与OptionID 中的内容匹配,那不是这样写的。

    如果您的意图是写“将节点的 BasePremium 值的内容与 OptionID 文本等于 @OptionID 更改为值 @R15_premium”,那么您可以这样做(嗯,一种方法这样做):

    SET @DataXml.modify('
        replace value of (
            /*
            /Premiums
            /DOPremium[child::OptionId/.=sql:variable("@OptionID")]
            /BasePremium
            /text()
        )[1] 
        with sql:variable("@R15_premium")')
    

    TotalPremium 也有类似的东西。当然,您也可以替换整个节点,但这似乎没有必要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 2013-03-30
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      相关资源
      最近更新 更多