2016-05-01 3 views
2

Почему запрос ниже не работает в 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
Conversion failed when converting the varchar value 'SCREEN' to data type int.

Колонка observ_value является varchar. Однако в подзапросе я уже выбрал значения int.

+0

просто FYI, я попробовал один и тот же запрос в MSSQL 2012, это работает. – Guoliang

+0

Показать некоторые данные образца – Mihai

ответ

2

К сожалению, оптимизатор запросов SQL Server может и переставить элементы из вашего запроса таким образом, что может привести к ошибкам, которые будут введены, которые не были там в исходном запросе. Это в значительной степени зависит от точного плана запросов, который используется, что, в свою очередь, зависит не только от определения таблицы и текста запроса, но и от того, как распределяются ваши значения.

В вашем случае, возможно, что SQL Server будет проверять observ_value >= 190, неявно преобразования 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 
+0

Sql-сервер не является mysql, он выдает ошибку для WHERE observ_value> = 190, если он не является числовым – Mihai

+0

@Mihai Я не знаю, имеете ли вы значение «если тип данных наблюдений не является числовым» или «если значение наблюдаемой_значения не является числовым ". Если первое: SQL Server с радостью преобразует столбцы 'varchar' в' int' неявно, и это хорошо документировано и поддерживается. Если последнее, да, следовательно, ошибка, полученная OP, и я решаю ошибку, убедившись, что 'observ_value' * никогда не является числовым: если исходное значение в таблице содержало какой-либо нецифровой символ, Выражение CASE 'оценивается как' NULL', которое безопасно конвертировать. – hvd

1

Вы можете использовать ISNUMERIC функция

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

Вы хотите сказать, что это избавит вас от ошибки? Я не понимаю, почему это так, но я могу что-то упустить. Если вы этого не говорите, это должен был быть комментарий. – hvd

Смежные вопросы