Падает простейший запрос. Помогите найти причину!

uaggster
Дата: 23.01.2013 15:55:20
Коллеги, просветите в отношении поведения оптимизатора!

Имеется MSSQL2008R2. Имеется некая таблица, в которой дата хранится в текстовом виде, dd.mm.yyyy, причем некоторые даты - кривые (не даты, мусор, Null-ы и т.д.).

Не работает вот такой запрос:
Set Dateformat dmy;
Select 137, a.ID from (
			select p.id, p.dr, p.DDEAD from dbo.PERSON p 
			 Where IsDate(p.DR)=1 and IsDate(p.DDead)=1
		 ) a
		where not convert(date, a.DDead, 104) between convert(date, a.DR, 104) and GETDATE()

Сообщение 241, уровень 16, состояние 1, строка 2
Conversion failed when converting date and/or time from character string.

Причем внутренний запрос - нормально отрабатывает и возвращает пустой набор (ну, ничего не возвращает).

Смотрю как баран на новые ворота.
В чем проблема?
Glory
Дата: 23.01.2013 16:00:07
uaggster
В чем проблема?

В том, что вы считаете, что сначала обязательно выполнится вложенный запрос. А потом только конвертация.
А сервер может эти операции выполнять в разном порядке.
X-Cite
Дата: 23.01.2013 16:01:47
Во внутреннем запросе сконвертируйте p.DDEAD в NVARCHAR и в WHERE обратно конвертируйте в Date
iap
Дата: 23.01.2013 16:02:03
uaggster,

проблема в том, что сервер выполняет CONVERT() ДО WHERE в подзапросе (ну, так ему захотелось!).
А вот, например, последовательность проверок в CASE он никогда не меняет!
Так что повторите проверку во внешнем WHERE с помощью CASE
Мистер Хенки
Дата: 23.01.2013 16:02:05
какое то значение p.DR или p.DDead не в 104 формате
samoxod
Дата: 23.01.2013 16:03:30
uaggster,
А если добавить условие :
where a.DDead is NOT NULL AND  a.DR IS NOT NULL AND (not convert(date, a.DDead, 104) between convert(date, a.DR, 104) and GETDATE())
iap
Дата: 23.01.2013 16:04:11
Мистер Хенки
какое то значение p.DR или p.DDead не в 104 формате
Да там есть просто мусор, как автор говорит.
Мистер Хенки
Дата: 23.01.2013 16:04:17
Мистер Хенки
какое то значение p.DR или p.DDead не в 104 формате

select convert(date,'2013-01-23 10:10:10',104)
но
select ISDATE('2013-01-23 10:10:10')
iap
Дата: 23.01.2013 16:07:01
samoxod
uaggster,
А если добавить условие :
where a.DDead is NOT NULL AND  a.DR IS NOT NULL AND (not convert(date, a.DDead, 104) between convert(date, a.DR, 104) and GETDATE())
NULL преобразуется в DATE просто замечательно (как и в любой другой тип).
Проблема не в NULL.

Кстати, порядок вычисления предикатов тоже выбирает сервер!
iap
Дата: 23.01.2013 16:10:57
Мистер Хенки
Мистер Хенки
какое то значение p.DR или p.DDead не в 104 формате

select convert(date,'2013-01-23 10:10:10',104)
но
select ISDATE('2013-01-23 10:10:10')
А так?
SET DATEFORMAT YDM
select ISDATE('2013-01-23 10:10:10')