SQL: ошибка при попытке отфильтровать все даты старше текущей - PullRequest
1 голос
/ 12 января 2012

Я использую SQL SERVER 2008. У меня есть таблица, в которой даты хранятся в формате даты и времени (т.е. 2012-01-21 15:00:00.000)

Я пытаюсь отфильтровать все даты старше, чем "сегодня".Поэтому я пытался сделать это, используя запрос ниже.

SELECT Date
  FROM MyTable
 WHERE Date >= GETDATE()

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

Conversion failed when converting date and/or time from character string.

Есть ли что-то, что я делаюнеправильно?Спасибо за помощь и дайте мне знать, если мне нужно предоставить больше информации!

Дополнительная информация:

[Date] имеет тип DateTime в MyTable.

У меня также есть вид, который просто выбирает [Дата] и не манипулирует

Я получаю доступ к [Дата] через вид

Ответы [ 5 ]

1 голос
/ 12 января 2012

Похоже, ваш столбец не относится к типу данных DATETIME.Это вероятно VARCHAR или подобное.Если вы предоставите DDL для создания таблицы, это позволит получить более конкретный ответ.

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

Вы не говорите, в какой локали вы находитесь, так как это будет иметь значение .Скорее всего, ваш столбец DATE не является DATETIME.Вы не говорите, в какой локали вы находитесь, но (в качестве примера) форматы даты и времени США и Великобритании обрабатываются по-разному в обратном формате.

Великобритания видит дату как yyyy-dd-mm hh:mm:ss.fff
США видит датуas yyyy-mm-dd hh:mm:ss.fff

Например, выдается ошибка:

SET LANGUAGE british
GO
SELECT CAST ('1999-01-21 10:11:12.345' AS DATETIME)
GO

Однако, если вы измените локаль на us_english, она будет правильно проанализирована.

Если вы хотите гарантировать, что он всегда будет анализироваться как yyyy-mm-dd, тогда вам нужно быть строгим и использовать полную спецификацию ISO, указав Z между датой и временем, например: 1999-01-21Z10:11:12.345 проанализирует водинаково в обеих локалях.

В конечном итоге вы хотите изменить столбец Date на тип данных DATETIME, но вам может понадобиться временно изменить вашу локаль, чтобы иметь возможность сделать это успешно;то есть:

SET LANGUAGE us_english
GO
ALTER TABLE [...]
GO
SET LANGUAGE british
GO

Еще одна забавная вещь, на которую нужно обращать внимание при манипулировании данными даты / времени.

Sidenote: нет Я не знаю, почему Microsoft думает насв Блайти видят дату как гггг-дд-мм ... Я никогда не сталкивался с этим форматом.Может быть унаследован от европейских форматов?

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

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

ХОРОШИЙ ПРИМЕР:

SELECT *
INTO #Temp
FROM
(
    SELECT '2010-01-21 15:00:00.000' [Date] UNION
    SELECT '2012-01-21 05:30:00.000' [Date] UNION
    SELECT '2015-01-21 07:45:00.000' [Date] UNION
    SELECT '2020-01-21 11:20:00.000' [Date]
) x

SELECT *
FROM #Temp
WHERE [Date] > GETDATE()

DROP TABLE #Temp

СРОК ПРИМЕР:

SELECT *
INTO #Temp
FROM
(
    SELECT '2010-01-21 15:00:00.000' [Date] UNION
    SELECT '2012-01-21 05:30:00.000' [Date] UNION
    SELECT '2015-01-21 07:45:00.000' [Date] UNION
    SELECT 'a2020-01-21 11:20:00.000' [Date]
) x

SELECT *
FROM #Temp
WHERE [Date] > GETDATE()

DROP TABLE #Temp

'a' в последней записи разбитого примера вызовет ошибку, которую вы получаете.

РАБОТАЕТ В РАМКАХ

SELECT *
INTO #Temp
FROM
(
    SELECT '2010-01-21 15:00:00.000' [Date] UNION
    SELECT '2012-01-21 05:30:00.000' [Date] UNION
    SELECT '2015-01-21 07:45:00.000' [Date] UNION
    SELECT 'a2020-01-21 11:20:00.000' [Date]
) x

SELECT *
FROM
(
    SELECT CASE WHEN ISDATE([Date]) = 1 THEN [Date] ELSE '' END [Date]
    FROM #Temp
) x
WHERE [Date] > GETDATE()

DROP TABLE #Temp

ЛУЧШИЙ ВАРИАНТ

SELECT *
INTO #Temp
FROM
(
    SELECT '2010-01-21 15:00:00.000' [Date] UNION
    SELECT '2012-01-21 05:30:00.000' [Date] UNION
    SELECT '2015-01-21 07:45:00.000' [Date] UNION
    SELECT 'a2020-01-21 11:20:00.000' [Date]
) x

SELECT *
FROM #Temp
WHERE CASE WHEN ISDATE([Date]) = 1 THEN [Date] ELSE '' END > GETDATE()

DROP TABLE #Temp
0 голосов
/ 12 января 2012

Если ваш столбец даты - VARCHAR/NVARCHAR, вам нужно преобразовать это значение в DATETIME.Исходя из вашего примера, правильный формат должен быть:

SELECT [Date]
  FROM MyTable
 WHERE CONVERT(DATETIME,[Date],121) >= GETDATE()
0 голосов
/ 12 января 2012

Прежде всего вы должны изменить это на:

SELECT [Date]
  FROM MyTable
 WHERE [Date] <= GETDATE()

Этот тип столбца [Дата] ????

...