T-sql - преобразование типа данных nvarchar в тип данных datetime привело к значению вне допустимого диапазона.Различия между = и НРАВИТСЯ - PullRequest
1 голос
/ 06 января 2012

У меня есть запрос с приведенными ниже предложениями WHERE

WHERE
    I.new_outstandingamount = 70
    AND ISNUMERIC(SUBSTRING(RA.new_stampernumber,7, 4)) = 1
    AND (DATEDIFF(M,T.new_commencementdate, SUBSTRING(RA.new_stampernumber,7, 10)) >= 1)
    AND RA.new_applicationstatusname = 'Complete'
    AND I.new_feereceived > 0
    AND RA.new_stampernumber IS NOT NULL
    AND T.new_commencementdate IS NOT NULL

RA.new_stampernumber - это строковое значение, которое содержит три объединенных фрагмента информации одинаковой длины.Средняя часть информации в этой строке - это дата в формате yyyy-MM-dd.

Чтобы отфильтровать все строки, в которых дата в этой строке не отформатирована, как ожидалось, я проверяю, чтобы увидетьесли первые 4 символа являются числовыми с использованием функции ISNUMERIC.

Когда я запускаю запрос, я получаю сообщение об ошибке, говорящее

The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.

Строка, которая вызывает эту ошибку,

AND (DATEDIFF(M,T.new_commencementdate, SUBSTRING(RA.new_stampernumber,7, 10)) >= 1)

Когда я закомментирую эту строку, я не получаю сообщение об ошибке.

Странно, что если я заменим

AND ISNUMERIC(SUBSTRING(RA.new_stampernumber,7, 4)) = 1

на

AND SUBSTRING(RA.new_stampernumber,7, 4) IN ('2003','2004','2005','2006','2007','2008','2009','2010', '2011', '2012','2013','2014','2015'))

, запрос будет успешно выполнен.

Что еще более странно, так это то, что если я заменю вышеуказанную рабочую строку на эту

AND SUBSTRING(RA.new_stampernumber,11, 1) = '-'

, я снова получаю сообщение об ошибке.Но если я заменяю знак равенства на сравнение LIKE, оно работает:

AND SUBSTRING(RA.new_stampernumber,11, 1) LIKE '-'

Когда я удаляю функцию DATEDIFF и сравниваю результаты каждого из этих запросов, они все возвращают один и тот же набор результатов, поэтому он не вызываетсяразными данными, возвращаемыми разными пунктами.

Может кто-нибудь объяснить мне, что может вызывать ошибку вне диапазона для некоторых предложений, а не для других, если возвращаемые данные фактически одинаковы для каждого предложения?

Спасибо, Нил

1 Ответ

0 голосов
/ 06 января 2012

Различные планы исполнения.

Нет гарантии, что пункты WHERE обрабатываются в определенном порядке. Предположительно, когда это работает, происходит отфильтровывание ошибочных строк перед попыткой приведения к дате.

Также ISNUMERIC сам по себе не очень надежен для того, что вы хотите. Я бы изменил выражение DATEDIFF на что-то вроде ниже

DATEDIFF(M, T.new_commencementdate, 
                    CASE
                    WHEN RA.new_stampernumber LIKE 
                    '______[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%' 
                     THEN SUBSTRING(RA.new_stampernumber, 7, 10)
                     END) >= 1 ) 
...