2013-04-22 59 views
2

值我想问一个有关和节点的价值观问题:如果您执行这一点,retrun奇怪的SQL Server的行为时,和节点在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 

sum some xml nodes values in sql server 2008

请考虑以下代码这个错误:

Msg 8114, Level 16, State 5, Line 8 Error converting data type nvarchar to 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中做到这一点?

回答

3

SQL Server有一个问题从一个字符串转换用科学记数法的数值为整数,当您运行XPath查询作为会发生,但是,它可以为float做到这一点。

你可以编写这样的查询:

select @xml.value('sum(/Parent[@ID = "p"]/Child) cast as xs:long?', 'bigint') 
+0

为什么一些整数应该在sql server中成为科学数字? – Arian 2013-04-22 11:48:19

+0

这就是您的xpath查询如何从sum()(http://msdn.microsoft.com/zh-cn/library/ms256160.aspx)返回'number'而不是'int'它到SQL Server。 – muhmud 2013-04-22 11:50:25

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 
+0

谢谢,但我想知道为什么SQL Server可以不投结果'bigint' – Arian 2013-04-22 11:28:33

+0

我更新了这个答案与BIGINT还是它的工作。请让我知道你想要哪种格式。 – Anvesh 2013-04-22 11:35:15

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') 

UPDATE:

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)') 
+0

谢谢,但它不适用于此:' 100000000000000 ' – Arian 2013-04-22 11:41:53

+0

请尝试更新的答案。 – Devart 2013-04-22 11:43:00

+0

对不起,它不适用于浮点数。更好的版本是:'CAST(@ xml.value('sum(/ Parent [@ ID =“p”]/Child)','float')AS BIGINT)' – Arian 2013-04-22 11:46:45

0

你这里的XML是非类型化XML。这意味着提供给sum()的值的类型为xdt:untypedAtomic。在xdt:untypedAtomic上使用sum()时,值将转换为xs:doublesum()的结果被values()函数读取为字符串(或无类型原子),当值小于1.0E-6或大于或等于1.0E6时,xs:double使用科学记数法。 SQL Server无法从科学计数法转换为intbigint

价:
sum Function (XQuery)
Type Casting Rules in XQuery

其他答案已经提供了浇铸的输入值或从结果或sum()使用floatvalues()数据类型的解决方法。另一种选择可以是使用类型化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