为什么这个查询不起作用?

时间:2016-05-01 07:38:33

标签: sql sql-server tsql

为什么下面的查询在SQL Server 2008中不起作用?

SELECT 
    CONVERT(INT, TEMP.observ_value) AS value
FROM
    (SELECT observ_value 
     FROM LAB_RESULTS
     WHERE observ_value NOT LIKE '%[^0-9]%') TEMP  
WHERE 
    observ_value >= 190

这里是错误:

  

Msg 245,Level 16,State 1,Line 5
  转换varchar值时转换失败'屏幕'数据类型int。

observ_value列为varchar。但是,我只选择了子查询中的int值。

2 个答案:

答案 0 :(得分:2)

不幸的是,SQL Server查询优化器可以并且将重新排列查询中的项目,这些方式可能会导致引入原始查询中不存在的错误。这在很大程度上取决于所使用的精确查询计划,而后者又不仅取决于表定义和查询文本,还取决于您的值的分布方式。

在您的情况下,在检查observ_value >= 190之前,SQL Server可能会检查observ_value,隐式地将int转换为observ_value NOT LIKE '%[^0-9]%'。这是否是对查询的有效重新排序是有争议的,但即使它无效,它也是SQL Server所做的事情,也是你必须解决的问题。

重新编写您的查询,以确保无法将非数字值转换为int

SELECT 
    TEMP.observ_value AS value
FROM
    (SELECT CASE
         WHEN observ_value NOT LIKE '%[^0-9]%'
         THEN CONVERT(INT, observ_value) END
         AS observ_value
     FROM LAB_RESULTS
     WHERE observ_value NOT LIKE '%[^0-9]%') TEMP  
WHERE 
    observ_value >= 190

答案 1 :(得分:1)

您可以使用ISNUMERIC功能

SELECT CONVERT(INT, observ_value) AS value
    FROM LAB_RESULTS
    WHERE  ISNUMERIC(observ_value)= 1