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

发布于 2024-12-29 13:44:09 字数 852 浏览 1 评论 0原文

首先,我要声明,我读过各种类似的帖子,但无法识别其他发帖者遇到的此错误消息问题与我遇到的情况之间的相似之处。也许我没有正确搜索,但情况如下。我试图在表中搜索转换为数值后小于 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

这会返回预期值,但它不是我尝试搜索的唯一名称。其他示例包括('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

不幸的是这样做这是我收到错误消息的地方。如果这个问题已经在其他地方得到了回答,我深表歉意。请链接,我将在信用到期时给予信用。

First, let me state I have read various similar posts and haven't been able to identify the similarities between the problem that other posters have had with this error message and the situation I've encountered. Perhaps I'm not searching correctly, but here's the scenario. I'm trying to search for values in a table that are less than 70 when converted to a numeric value. Sometimes the value can be stored with a comma (i.e. 3,080 etc.) so I have a replace statement to remove the comma. The obsValue column in the queries below is varchar(2000) and I'm guessing that may have something to do with it. My initial query worked:

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

This brings back expected values, but it's not the only name I'm trying to search for. Other examples include ('LDL(CALC)'). Using a UNION statement will allow me to union queries together but unfortunately I don't control the application code and this is not an option. The only option I have available is using an IN clause, so ultimately the query will look like this when I'm searching for a variety of name values:

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

And unfortunately doing it this way is where I get the error message. I apologize if this has already been answered elsewhere. Please link and I will give credit where credit is due.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌伤ぢ 2025-01-05 13:44:09

您可以将 IsNumeric(obsvalue) 替换为 (select obsvalue where 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

You can replace the IsNumeric(obsvalue) with (select obsvalue where 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
分分钟 2025-01-05 13:44:09

obsvalue 中可能有一些值对于您的强制转换(作为十进制)函数来说太大,但您无论如何都不关心,因为它们不符合您的 in() 标准。

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

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

There may be values in obsvalue that are too big for your cast( as decimal) function but you don't care about anyways because they don't meet your in() criteria.

Try applying the cast() in a subquery, limiting your query to obsvalues you actually need to convert.

Also, since the commas only exist if the value is greater than 999, and you're testing for values less than 70, you don't need the replace. In fact, you could exclude any row containing a comma because you know it's too high.

草莓酥 2025-01-05 13:44:09

问题在于,当 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

The problem is that SQL Server is optimizing the query differently when there are multiple items in the IN clause. You can use a CASE statement to prevent the optimization

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文