我问一个关于sum节点值的问题:
sum some xml nodes values in sql server 2008
请考虑以下代码:
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
如果执行此操作,则会重新发出此错误:
Msg 8114,Level 16,State 5,Line 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会这样做?
答案 0 :(得分:4)
Sql Server在使用科学记数法将值从字符串转换为整数时遇到问题,就像运行xpath查询时一样,但是,它可以为float
执行此操作。
您可以像这样编写查询:
select @xml.value('sum(/Parent[@ID = "p"]/Child) cast as xs:long?', 'bigint')
答案 1 :(得分: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)')
答案 2 :(得分: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
答案 3 :(得分:0)
您在此处使用的XML是无类型XML。这意味着提供给sum()
的值的类型为xdt:untypedAtomic
。在sum()
上使用xdt:untypedAtomic
时,值会转换为xs:double
。 sum()
函数将values()
的结果作为字符串(或untypedAtomic)读取,xs:double
使用科学记数法,当值小于1.0E-6或大于或等于1.0E6。 SQL Server无法将科学记数法转换为int
或bigint
。
价:
sum Function (XQuery)
Type Casting Rules in XQuery
其他答案提供了变通方法,可以将sum()
或float
的输入值或结果作为values()
中的数据类型。另一种选择可能是使用类型化的XML。
架构:
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