Почему сообщение об ошибке SQL Conversion неудачно (дата) в некоторых случаях, но не другие?

63
6

Я столкнулся с очень странной проблемой с SQL-запросом, в котором появляется сообщение об ошибке "Ошибка конверсии при преобразовании даты и/или времени из символьной строки". неожиданно (ну я этого не ожидал), но с разными манипуляциями с запросом какая-то работа, а другие нет. Поэтому у меня есть рабочее решение, но я хочу понять, почему некоторые пути не работают, а некоторые -.

Предпосылки: myTable - таблица с myDateAsString, которая содержит даты как строки в формате dd/mm/yyyy. Я не могу изменить это или изменить структуру базы данных в любом случае, но хочу вытащить некоторые данные как даты для обработки.

Первоначальное извлечение данных: это работает (но не имеет желаемого предложения WHERE для сужения данных (я ожидал бы, если бы были данные, которые не будут его конвертировать, это приведет к ошибке здесь)

SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable

Добавление предложения WHERE: я хочу только извлекать данные, которые "в будущем"; так как запрос выше работает, я ожидаю, что это тоже сработает, но оно выдает сообщение об ошибке "Ошибка конверсии при преобразовании даты и/или времени из символьной строки".

SELECT *
FROM (
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable) as ConvertedData
WHERE myDate > GETDATE()

Есть ли причина, по которой это не удается? Все данные выглядят как правильные даты (в частности, поскольку запрос "извлечения исходных данных" выше не прерывается.

Для выражения общей таблицы: казалось (из поисков), что вышеизложенное может выйти из строя на основе порядка выполнения и т.д., Поэтому я подумал, что CTE на помощь и попытался выполнить следующее

WITH ConvertedData_CTE (myDate)
AS
(
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable
)

SELECT *
FROM ConvertedData_CTE
WHERE myDate > GETDATE()

Снова сообщение об ошибке "Conversion failed при преобразовании даты и/или времени из символьной строки". (обратите внимание: если я удалю предложение WHERE без сообщения об ошибке)

Еще одна попытка: поэтому я попытался с табличной переменной как таковой

DECLARE @ConvertedData TABLE (myDate date)

INSERT INTO @CovertedData (myDate)
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable

SELECT *
FROM @ConvertedDate
WHERE myDate > GETDATE()

И к моему удивлению, это сработало.

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

EDIT: добавление выборочных данных

Пример данных

22/08/2013 10/03/2012 22/08/2012 24/08/2012 27/08/2012 21/08/2012 23/08/2013 15/03/2013 07/04/2010 22/08/2013 '//'

примечание: данные в исходной таблице имеют 3394 строки, и если я выберу первые 1010 строк, я могу заставить все запросы работать; эти данные представляют строки 1010-1020, где, если я ограничу исходную таблицу, она работает так, как описано... однако, если я создаю новую таблицу только с этими данными... тогда все запросы работают (это имеет смысл для меня как это то, что происходит в запросах, т.е. новая таблица, переменная таблицы, работает, но другие методы не надеются, что точки в каком-то хорошем направлении

EDIT: дополнительная информация, изначально не предоставленная для ясности. Вышеупомянутые запросы имеют дополнительное предложение WHERE, поскольку некоторые данные в базе данных (которые должны быть явно сохранены как NULL) сохраняются как "//". Таким образом, существует дополнительная WHERE myDateAsString <> '//' во всех вышеприведенных запросах: я обновляю образцы данных, чтобы включить этот элемент данных, а также, как ни странно, запросы все еще работают (только одна "плохая точка данных" и предложение <> в ней есть исключая)... вопрос по-прежнему заключается в исключении работ над SELECT, где происходит преобразование, но затем завершаются ошибки в WHERE с GETDATE(), которые будут после завершения преобразования?

спросил(а) 2021-01-25T22:00:19+03:00 5 месяцев назад
1
Решение
63

Я предполагаю, что некоторые из ваших данных текстовой даты либо повреждены, либо находятся в формате, который не может быть преобразован в дату. Чтобы очистить такие записи, вы можете попробовать использовать TRY_CONVERT:

SELECT *
FROM myTable
WHERE TRY_CONVERT(DATETIME, myDateAsString) IS NULL;

После того, как вы нашли неприятные строки, вы должны исправить свои данные, преобразовать столбец в тип даты и затем остановить сохранение информации о дате в виде обычного текста.

ответил(а) 2021-01-25T22:00:19+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема