SQL:尝试过滤掉当前日期之前的所有日期时出错

时间:2012-01-12 15:44:27

标签: sql sql-server-2008 datetime date

我正在使用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]在MyTable中的日期时间类型。

我还有一个只选择[日期]并且不进行操作的视图

我通过视图

访问[日期]

5 个答案:

答案 0 :(得分:1)

看起来您的列毕竟不是DATETIME数据类型。它可能是VARCHAR或类似的。如果您提供用于创建表的DDL,那么将允许更具体的答案。

答案 1 :(得分:0)

首先,您应该将其更改为:

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

那种类型的列是[Date] ????

答案 2 :(得分:0)

如果您的日期列为VARCHAR/NVARCHAR,则需要将该值转换为DATETIME。从您的示例中,正确的格式应为:

SELECT [Date]
  FROM MyTable
 WHERE CONVERT(DATETIME,[Date],121) >= GETDATE()

答案 3 :(得分:0)

如果要将varchar与日期时间进行比较,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

答案 4 :(得分:0)

您没有说明您的语言环境,因为 很重要。最可能的情况是您的DATE列不是DATETIME。您没有说明您的语言环境,但是(例如)美国和英国的日期时间格式在反向格式时会有不同的处理方式。

英国将日期视为yyyy-dd-mm hh:mm:ss.fff
美国将日期视为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,那么你需要严格并通过在日期和时间之间指定Z来使用完整的ISO规范,例如:{ {1}}将在两种语言环境中以相同的方式进行解析。

最终,您希望将1999-01-21Z10:11:12.345列更改为Date的数据类型,但您可能需要临时更改您的区域设置才能成功执行此操作;即:

DATETIME

操纵日期/时间数据时要注意另一个有趣的“问题”。

旁注:不,我不知道为什么微软认为我们在Blighty看到日期为yyyy-dd-mm ......我从未遇到过这种格式。可以继承欧洲格式吗?