2013-07-30 215 views
1

最近我正在玩SQL Server数据类型,并将大量数据放入表中,并尝试用Varchar和Numeric数据计算性能。但是,我得到了一些错误,这是我不认为不应该,但它是。我的问题是如下:具有Int和Decimal转换功能的Sql Server SUM函数

我有一个表:

create table sa(f1 varchar(100)) 

我有一个存储过程,而插入100000个数据到表:

create proc sad 
as 
begin 
    declare @i int=0 
    while @i<100000 
    begin 
     insert into sa values(@i) 
     set @[email protected]+1 
    end 
end 


exec sad 

而且我已经测试了以下内容:

select CONVERT(int,f1) from sa //Works Fine, i tested after the Problem 
select sum(convert(int,f1)) from sa //Didn't Worked, So i tested above and Below 
select sum(convert(decimal(18,2),f1)) from sa //And, it again works fine 

但是,当我总结转换F1到INT,它显示我一个错误。
但是,当我只选择转换为Int罚款。
而且,当我总结转换F1到十进制它工作正常。

什么是SUM函数的数据类型?
在上面的数据它适用于十进制,但不是诠释?
为什么?

即时得到以下错误

算术溢出错误将表达式转换为数据类型int。

+0

请复制并粘贴您收到的错误... –

+0

对不起,我编辑了我的问题,并收到了错误 –

+0

我试图找出性能问题,同时使用Varchar和数字数据类型 –

回答

4

根据MS文档(参见https://docs.microsoft.com/en-us/sql/t-sql/functions/sum-transact-sql),则SUM()函数返回一个不同类型的值,根据该列的数据类型您正在添加:如果该列的类型为int,tinyintsmallint,则SUM会返回类型为int的值。

转换为bigintdecimal品牌SUM()返回一个较大的数据类型,这也解释了为什么在这种情况下,你没有溢出。

+0

好的,那么总和取决于我们正在求和的列数据类型。谢谢。这让我清楚。 –

7

您的总和为INT,其范围不能保留该总和。

DECIMAL可以。

1到99999之间的所有值的总和为4999950000,最大INT值为2147483647,小于总和结束为的一半。

当你加上INT的时候,你会得到一个新的INT。当你总结DECIMAL的时候,你会得到一个新的DECIMAL,所以输入类型定义了输出类型。

您可以改用bigint代替,它应该“没问题”。

此外,在第二个注意,请不要存储数字作为文本

+0

雅,我不应该。但为什么?当我将它转换为SUM时,SUM函数是否将其数据类型导出为INT? –

+0

是的。输入是INT,输出是INT。 –

+0

如何,总和取决于INT,在这里转换成INT工程嘛。而且,转换成十进制也很好。那么,为什么Summing(int)没有工作,但它可以转换,但为什么sum作品Decimal? –

2

期待您已超过最大int值SQL Server允许(2,147,483,647) - 见https://docs.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql

十进制允许高达10^38 - 1的更高限制(即1个38之后的0) - 请参阅https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql

但是,如果值的类型为int,我不建议转换为decimalDecimal如果数字具有已知精度和比例的小数点后的可能数字(例如货币,百分比等),则此值非常有用。)作为另一的海报曾建议,这里的最佳的转换将是一个bigint

select sum(cast(f1 as bigint)) from sa