简体   繁体   中英

Why this query doesn't work?

Why the query below doesn't work in 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

Here, is the error:

Msg 245, Level 16, State 1, Line 5
Conversion failed when converting the varchar value 'SCREEN' to data type int.

The observ_value column is varchar . However, I have already only chosen the int values in the subquery.

Unfortunately, the SQL Server query optimiser can and will rearrange items from your query in ways that may cause errors to be introduced that weren't there in your original query. This is heavily dependent on the precise query plan that gets used, which in turn depends not only on the table definition and query text, but also on how your values are distributed.

In your case, it's possible that SQL Server will check observ_value >= 190 , implicitly converting observ_value to int , before checking that observ_value NOT LIKE '%[^0-9]%' . Whether this is a valid re-ordering of your query is arguable, but even if it's not valid, it's something SQL Server does and something you have to work around.

Re-write your query to make sure no conversion of non-numeric values to int can ever be performed:

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

You can use ISNUMERIC function

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM