Вы не можете форсировать порядок, в котором механизм запросов будет пытаться обработать оператор без предварительного сброса строк ISDATE() = 1
в таблицу #temp.Вы не можете гарантировать порядок обработки или короткое замыкание, даже если некоторые предложат использовать CTE или подзапрос, чтобы сначала отфильтровать плохие строки.Поэтому некоторые могут предложить:
;WITH x AS
(
SELECT mat3_02_01, mat3_04_02
FROM Intmu11.matter3
WHERE ISDATE(mat3_04_02) = 1
AND mat3_04_02 IS NOT NULL -- edited!
)
SELECT mat3_02_01, CONVERT(DATETIME, mat3_04_02), mat3_04_02
FROM x
ORDER BY mat3_04_02 DESC;
И это может даже сработать сегодня.Но в долгосрочной перспективе действительно единственный способ гарантировать этот порядок обработки - в текущих версиях SQL Server - это:
SELECT mat3_02_01, mat3_04_02
INTO #x
FROM Intmu11.matter3
WHERE ISDATE(mat3_04_02) = 1
AND mat3_04_02 IS NOT NULL; -- edited!
SELECT mat3_02_01, CONVERT(DATETIME, mat3_04_02), mat3_04_02
FROM #x
ORDER BY mat3_04_02 DESC;
Задумывались ли вы о проверке значений на входе?Например, вы можете изменить место появления этой ошибки в приложении, ударив их по запястью, когда они вводят недопустимую дату, вместо того, чтобы наказывать человека, который выбирает их неверные данные.Если вы управляете обновлением / вставкой с помощью хранимой процедуры, вы можете сказать:
IF ISDATE(@mat3_04_02) = 0
BEGIN
RAISERROR('Please enter a valid date.', 11, 1);
RETURN;
END
Если вы не управляете манипулированием данными с помощью хранимых процедур, вы можете добавить проверочное ограничение ктаблица (после того, как вы очистили существующие неверные данные).
UPDATE Intmu11.matter3 SET mat3_04_02 = NULL
WHERE ISDATE(mat3_04_02) = 0;
ALTER TABLE Intmu11 WITH NOCHECK
ADD CONSTRAINT mat3_04_02_valid_date CHECK (ISDATE(mat3_04_02)=1);
Таким образом, когда сообщение об ошибке всплывает пользователю, он увидит имя ограничения и, надеюсь, сможет сопоставить его сточка ввода данных на внешнем интерфейсе, которая не смогла:
Сообщение 547, уровень 16, состояние 0, строка 1
Оператор INSERT конфликтует с ограничением CHECK "mat3_04_02_valid_date".Конфликт произошел в базе данных «your_db», таблице «Intmu11.matter3», столбце «mat3_04_02».
Оператор завершен.
Или еще лучше, используйте правильный тип данных впервое место!Опять же, после обновления существующих неверных данных на NULL
, вы можете сказать:
ALTER TABLE Intmu11.matter3 ALTER COLUMN mat3_04_02 DATETIME;
Теперь, когда кто-то пытается ввести не дату, он получит ту же ошибку, что и пользователи в настоящее время.получить, когда они пытаются выбрать неверные данные:
Msg 241, уровень 16, состояние 1, строка 1
Преобразование не удалось при преобразовании даты и / или времени из строки символов.
В SQL Server 2012 вы сможете обойти это с помощью TRY_CONVERT()
, но вам все равно следует пытаться получить тип данных с самого начала.