【问题标题】:SQL Server variable give me singleton errorSQL Server 变量给我单例错误
【发布时间】:2025-12-28 07:00:12
【问题描述】:

我在一个表中有一个XML 列,其结构如下

<md xmlns="http://www.intellipayment.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <dist>
    <ml>
      <S>368.72</S>
      <src>26249201</src>
      <t>26249202</t>
    </ml>
    <ml>
    ....
    </ml>
  </dist>
</md>

我想把所有的src全选出来,一一操作。

所以我的SQL语句是:

while @i <= @xmlCount
begin
    select 
        @CurrentSrc = AssignmentDistribution.value('(/*:md/*:dist/*:ml/*:src/text())[sql:variable("@i")]', 'varchar(50)')
    from 
        table 
    where 
        id = 1234

    set @i = @i + 1
end

我收到此错误:

XQuery [autodeals.AssignmentDistribution.value()]: 'value()' 需要一个单例(或空序列),找到类型为 'xdt:untypedAtomic *' 的操作数

但是,如果我将 SQL 变量替换为静态数字 1、2、3、4 ..... 它会正确显示结果。

谁能告诉我我做错了什么?

谢谢

【问题讨论】:

    标签: xml sql-server-2008


    【解决方案1】:

    这可能是因为sql:variable() 返回xdt:anyAtomicType,我不确定。但这是一种可能的替代方法,首先使用query(),它不限制只返回单例,然后使用value() 函数将返回值转换为varchar(50)

    select @CurrentSrc = AssignmentDistribution
                             .query('(/*:md/*:dist/*:ml/*:src/text())[sql:variable("@i")]')
                             .value('.', 'varchar(50)')
    FROM table where id = 1234
    

    【讨论】:

      【解决方案2】:

      如果您将此方法与 .nodes() 调用一起使用,则无需手动执行任何循环 - 您将 src 值作为一个很好的关系数据集,您可以对它们进行操作.... .

      ;WITH XMLNAMESPACES(DEFAULT 'http://www.intellipayment.com'),
      SrcFromXml AS
      (
          SELECT
              Id,
              Src = XC.value('(src)[1]', 'int')
          FROM
              table 
          CROSS APPLY
              AssignmentDistribution.nodes('/md/dist/ml') AS XT(XC)
      )
      SELECT *
      FROM SrcFromXml
      

      【讨论】:

      • 感谢您的回复。我知道这个解决方案,但我更感兴趣的是为什么它会给我一个错误。
      • @KennethLam:一个的原因是您完全忽略了文档上的 XML 命名空间,并且您尝试选择好像没有 XML命名空间在起作用。
      • 名称空间不是问题。我想出了如何在不指定命名空间的情况下使用 sql 变量进行选择。
      最近更新 更多