使用SUM函数偶尔转换错误

时间:2009-08-10 14:44:57

标签: sql-server tsql

我的应用程序使用sql2000,它使用的select语句有时会失败。每周大约一次,select会返回错误

'错误将数据类型varchar转换为数字'

SQL:

sum(case when ISNULL(form_prsn_id, -1) = irpd_prsn_id 
                          then convert(dec(11,2), case when valu_value = '' 
                                                       then '0' 
                                                       else isnull
(valu_value,'0') 
                                                        end)* case when  
fmdt_deduction_flag = 'Y' 
                                                                   then -1 
                                                                   else 1 
                                                                    end 
                          else 0 
                           end) as client_sum

valu_value字段是varchar并存储一些数字和一些varchar。但包括我的join和where子句过滤器

它将始终选择数字或空字符串。 当它失败时,我可以删除SUM,查看数据并知道它的数字。 那么为什么SUM函数有时(比如5%的时间)会对数字数据失败。 我想知道SQL是否以某种方式“向前看”以确保它可以转换为十进制而不仅仅是返回没有总和的行。 注意我发现了一个包含的修复(其中isNumeric(valu_value)= 1)

由于

4 个答案:

答案 0 :(得分:1)

这种事情发生(有时)。问题(几乎)始终存在于SQL Server为您的查询生成的执行计划中。在加入/条件运算符之前,SQL Server可能会发生转换。这就是你收到错误的原因。

使用提示强制执行特定的[执行]计划或引入其他条件(正如您所做的那样)是解决此类问题的关键。

答案 1 :(得分:0)

试试这个:

sum(case
        when ISNULL(form_prsn_id, -1) = irpd_prsn_id then convert(dec(11,2), case
                                                                                 when ISNUMERIC(valu_value)=1 THEN valu_value
                                                                                 else 0
                                                                             end
                                                                 )* case
                                                                        when fmdt_deduction_flag = 'Y' then -1 
                                                                        else 1 
                                                                    end 
        else 0 
    end
   ) as client_sum

区别在于:

OLD

case
    when valu_value = ''  then '0'
    else isnull(valu_value,'0')
end

NEW

case
    when ISNUMERIC(valu_value)=1 THEN valu_value
    else 0
end

答案 2 :(得分:0)

只是快速思考,因为您没有说明如何确保valu_value是数字,但它可以包含逗号吗? e.g。

select isnumeric('23,00')

PASS!

select convert(dec(11,2),'23,00')

FAIL - 将数据类型varchar转换为数字时出错。

答案 3 :(得分:0)

我之前遇到过这种情况,因此根本原因可能是SQL Server 2005进程转换之前的转换或where语句基于执行计划。

我的情况是:

SELECT Convert(decimal(18,0), NVarcharColumn) FROM Table1

我通过将语句更改为:

来解决它
SELECT Convert(decimal(18,0), NVarcharColumn) FROM Table1
WHERE isnumeric(NvarcharColumn) = 1