将varchar转换为数据类型numeric的算术溢出错误

时间:2012-01-30 16:41:55

标签: sql sql-server-2005 isnumeric

首先,让我说明我已阅读过各种类似的帖子,但未能确定其他海报对此错误信息的问题与我遇到的情况之间的相似之处。也许我没有正确搜索,但这是场景。我正在尝试在转换为数值时在表中搜索小于70的值。有时值可以用逗号存储(即3,080等),所以我有一个替换语句来删除逗号。以下查询中的obsValue列为varchar(2000),我猜这可能与它有关。我的初步查询有效:

Select name, obsValue
From database.dbo.table
Where name in ('LDL') 
and isnumeric(obsvalue) = 1 
and cast(replace(obsvalue,',','') as decimal(18)) < 70

这会带回预期值,但它不是我尝试搜索的唯一name。其他示例包括('LDL(CALC)')。使用UNION语句将允许我将查询联合在一起但不幸的是我不控制应用程序代码,这不是一个选项。我唯一可用的选项是使用IN子句,因此当我搜索各种name值时,查询最终会如下所示:

Select name, obsValue
From database.dbo.table
Where name in ('LDL', 'LDL(CALC)') 
and isnumeric(obsvalue) = 1 
and cast(replace(obsvalue,',','') as decimal(18)) < 70

不幸的是,这样做是我收到错误消息的地方。如果已经在其他地方回答过,我道歉。请链接,我会在信用到期时给予信用。

3 个答案:

答案 0 :(得分:1)

对于你的演员(十进制)函数,obsvalue中可能有一些值太大但你不关心,因为它们不符合你的in()标准。

尝试在子查询中应用cast(),将查询限制为实际需要转换的数据。

此外,由于逗号仅在值大于999时存在,并且您正在测试小于70的值,因此您不需要替换。实际上,您可以排除包含逗号的任何行,因为您知道它太高了。

答案 1 :(得分:1)

问题是当IN子句中有多个项目时,SQL Server正在以不同方式优化查询。您可以使用CASE语句来阻止优化

SELECT name, obsvalue
FROM database.dbo.table 
WHERE (CASE WHEN ( isnumeric(obsvalue) = 1 
             AND name in ('LDL', 'LDL(CALC)')) 
       THEN cast(replace(obsvalue,',','') as decimal(18))
       ELSE null END) < 70

答案 2 :(得分:1)

您可以将IsNumeric(obsvalue)替换为(选择obsvalue,其中isnumeric(obsvalue)= 1)。

Select name, obsValue
From database.dbo.table
Where name in ('LDL', 'LDL(CALC)') 
and isnumeric(obsvalue) = 1 
and cast(replace((select obsvalue where isnumeric(obsvalue) = 1),',','') as decimal(18)) < 70