SQL参数溢出错误在限制where子句中的值时将varchar转换为十进制

时间:2017-05-24 18:17:39

标签: sql-server

我有一个CTE查询,它将varchar字段转换为小数。 但是,在CTE之后的SELECT我想限制返回的值。 这是我得到

的时候
  

关节炎溢出错误

这是查询:

;WITH CTE
AS
(
SELECT PP.PatientProfileID, 
        ROUND(CAST( CASE WHEN ISNUMERIC(O.Value) = 1 THEN O.Value END AS DECIMAL(4, 1)), 1) AS BmiValue
FROM PatientProfile PP RIGHT OUTER JOIN Encounter E1 ON PP.PatientProfileID = E1.PatientProfileID
        JOIN Procedures P on E1.PatientEncounterID = P.PatientEncounterID
        JOIN Observation O ON O.PatientProfileID = E1.PatientProfileID
WHERE P.CPTCode = '3008F' AND
    O.Term = 'BMI' AND O.Value IS NOT NULL
)
SELECT * 
FROM CTE
WHERE BmiValue >= 18.5 AND BmiValue < 25.0

当我将where子句限制为:WHERE BmiValue >= 18.5时,没有错误。 当我只使用WHERE BmiValue < 25.0时,没有错误。 只有当我使用两个表达式时才会出现算术溢出错误。

查询有什么问题?

更新 正如我在评论中所说,我使用的是SQL SERVER 2008 R2。 我在CTE中消除了十进制值的空值。当我删除WHERE子句时,BmiValue的所有值都显示为十进制值。

如果我将BmiValues的选择范围缩小到此WHERE条款: WHERE (BmiValue >= 18.5) AND (BmiValue < 30.0) 没有算术溢出错误。 当我将最大值更改为: WHERE (BmiValue >= 18.5) AND (BmiValue < 29.0) 我得到算术溢出错误......很奇怪。

2 个答案:

答案 0 :(得分:4)

由于这是一个溢出错误,您可以尝试增加GetCallerIdentity的大小。不能保证decimal()没有其他问题。

cast()

在Sql Server 2012及更高版本中:当转换失败而不是错误时,每个都会返回;with CTE as ( select PP.PatientProfileID , ROUND(CAST(case when ISNUMERIC(O.Value) = 1 then O.Value end as decimal(19, 6)), 1) as BmiValue from PatientProfile PP right join Encounter E1 on PP.PatientProfileID = E1.PatientProfileID inner join Procedures p on E1.PatientEncounterID = p.PatientEncounterID inner join Observation O on O.PatientProfileID = E1.PatientProfileID where p.CPTCode = '3008F' and O.Term = 'BMI' and O.Value is not null ) select * from CTE where BmiValue >= 18.5 and BmiValue < 25.0

答案 1 :(得分:2)

你可能试图在空值上运行数学。

1)ISNUMERIC()不仅仅是数字(包括' - ','+','$'等)返回true。请转而使用TRY_CAST()

2)您的CASE语句需要ELSE子句。否则,您尝试CAST任意ISNUMERIC() = false(即空值)到DECIMAL

除此之外,在where子句中使用BETWEEN - 只是更清洁。