3

我问一个关于 sum 节点值的问题:

总结 sql server 2008 中的一些 xml 节点值

请考虑以下代码:

Declare @xml xml 
set @xml='<Parent ID="p">
     <Child ID="1">1000000000</Child > 
     <Child ID="2">234650</Child > 
     <Child ID="3">0</Child > 
      </Parent >'

Select @xml.value('sum(/Parent[@ID="p"]/Child)','bigint') as Sum

如果你执行它,它会重新运行这个错误:

消息 8114,级别 16,状态 5,第 8 行将数据类型 nvarchar 转换为 bigint 时出错。

问题是它返回这个值:1.00023465E9

如果我以这种方式更改上述查询,则可以:

Declare @xml xml 
set @xml='<Parent ID="p">
     <Child ID="1">1000000000</Child > 
     <Child ID="2">234650</Child > 
     <Child ID="3">0</Child > 
      </Parent >'

Select @xml.value('sum(/Parent[@ID="p"]/Child)','float') as Sum

为什么 Sql Server 会这样做?

4

4 回答 4

4

Sql Server 在将科学记数法的值从字符串转换为整数时遇到问题,就像在运行 xpath 查询时会发生的那样,但是,它可以为float.

你可以这样写你的查询:

select @xml.value('sum(/Parent[@ID = "p"]/Child) cast as xs:long?', 'bigint')
于 2013-04-22T11:34:18.580 回答
2

试试这个——

DECLARE @xml XML 
SELECT @xml='<Parent ID="p">
     <Child ID="1">1000000000</Child > 
     <Child ID="2">234650</Child > 
     <Child ID="3">0</Child > 
      </Parent >'

SELECT @xml.value('sum(for $r in /Parent[@ID="p"]/Child return xs:int($r))', 'bigint')

更新:

DECLARE @xml XML 
SELECT @xml='<Parent ID="p">
     <Child ID="1">100000000000000</Child > 
     <Child ID="2">234650</Child > 
     <Child ID="3">0</Child > 
      </Parent >'

SELECT @xml.value('sum(for $r in /Parent[@ID="p"]/Child return xs:decimal($r))', 'bigint')

更新 2:

DECLARE @xml XML 
SELECT @xml='<Parent ID="p">
     <Child ID="1">100000000000000.6</Child > 
     <Child ID="2">234650</Child > 
     <Child ID="3">0</Child > 
      </Parent >'

SELECT @xml.value('sum(for $r in /Parent[@ID="p"]/Child return xs:decimal($r))', 'decimal(18,2)')
于 2013-04-22T11:34:03.193 回答
0

试试这与 BIGINT 一起使用:

DECLARE @SearchKeyWords XML 

SET @SearchKeyWords =
'<Parent ID=''p''>
    <Child ID="1">1000000000</Child > 
    <Child ID="2">234650</Child > 
    <Child ID="3">0</Child > 
</Parent >' 

DECLARE @TempSearchKeyWords TABLE
        (
            SearchKeyWord BIGINT
        )

INSERT INTO @TempSearchKeyWords                     
SELECT SearchKeyWords.SearchKeyword.value('.',' bigint ') AS SearchKeyword             
FROM @SearchKeyWords.nodes('/Parent/Child') AS SearchKeyWords(SearchKeyword)

SELECT SUM(SearchKeyWord) FROM @TempSearchKeyWords
于 2013-04-22T11:27:20.620 回答
0

您在此处拥有的 XML 是无类型的 XML。这意味着提供给的值sum()是 type xdt:untypedAtomic。Whensum()用于xdt:untypedAtomic将值转换为xs:double. 的结果sum()values()函数作为字符串(或 untypedAtomic)读取,并xs:double在值小于 1.0E-6 或大于或等于 1.0E6 时使用科学计数法。SQL Server 无法从科学记数法转换为intor bigint

参考: XQuery 中的
sum 函数 (XQuery)
类型转换规则

其他答案提供了解决方法,将输入值或结果sum()从. 另一种选择是使用类型化的 XML。floatvalues()

架构:

create xml schema collection XSDSumTest as '
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Parent">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Child" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:int">
                                <xs:attribute name="ID" type="xs:int"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="ID" type="xs:string"/>
        </xs:complexType>
    </xs:element>
</xs:schema>'

询问:

declare @xml xml(XSDSumTest) = '
<Parent ID="p">
  <Child ID="1">1000000000</Child > 
  <Child ID="2">234650</Child > 
  <Child ID="3">0</Child > 
</Parent>'

select @xml.value('sum(/Parent[@ID="p"]/Child)','bigint') as Sum
于 2013-04-23T06:03:51.963 回答