我在这里有这个问题:
SELECT *
FROM QuestionnaireAnswer
WHERE dateCreated BETWEEN CAST('20/12/2015' AS datetime) AND CAST('22/12/2015' AS datetime)
但我一直收到这个错误,怎么回事?以及如何修复它?
将varchar数据类型转换为日期时间数据类型会导致超出范围的值。
答案 0 :(得分:7)
SQL Server支持多种格式 - 请参阅MSDN Books Online on CAST and CONVERT。大多数格式都是依赖你所拥有的设置 - 因此,这些设置可能会有效 - 有时也不会。
解决此问题的方法是使用SQL Server支持的(略微调整的) ISO-8601日期格式 - 此格式始终 - 无论您的是什么SQL Server语言和日期格式设置。
SQL Server支持ISO-8601 format有两种形式:
YYYYMMDD
仅适用于日期(无时间部分);请注意:没有破折号!,这非常重要! YYYY-MM-DD
不独立于SQL Server中的dateformat设置, NOT 可以在所有情况下使用!或:
YYYY-MM-DDTHH:MM:SS
了解日期和时间 - 请注意:此格式有破折号(但可以可以省略),还有一个固定的T
作为DATETIME
的日期和时间部分之间的分隔符。这适用于SQL Server 2000及更高版本。在具体案例中,请使用此WHERE
子句:
WHERE dateCreated BETWEEN '20151220' AND '20151222'
并且您甚至不需要任何明确的CAST
操作(或者如果您想使用明确的CAST
- 那么我建议您转换为DATE
数据类型 - 而不是DATETIME
)。
如果您使用SQL Server 2008或更高版本以及DATE
数据类型(仅DATE
- 不 DATETIME
!),那么您确实也可以使用YYYY-MM-DD
格式,也适用于SQL Server中的任何设置。
不要问我为什么整个主题都是如此棘手而且有点令人困惑 - 这就是它的方式。但是使用YYYYMMDD
格式,您可以适用于任何版本的SQL Server以及SQL Server中的任何语言和日期格式设置。
对于SQL Server 2008及更高版本的建议是,如果您只需要日期部分,则使用DATE
,当需要日期和时间时,使用DATETIME2(n)
。您应该尽可能尝试开始逐步淘汰DATETIME
数据类型
答案 1 :(得分:2)
作为比较SQL Server中日期的一般规则,请勿使用特定于区域设置的格式,请使用通用ISO 8601
格式'yyyy/MM/dd'
,以便查询变为:
SELECT *
FROM QuestionnaireAnswer
WHERE dateCreated BETWEEN CAST('2015/12/20' AS datetime) AND CAST('2015/12/22' AS datetime)
您还可以使用特定于区域设置的一个,但您必须确保服务器上的日期格式在您的代码将连接到的所有服务器上始终保持相同。
答案 2 :(得分:1)
使用CONVERT你可以这样写:
SELECT *
FROM QuestionnaireAnswer
WHERE
dateCreated BETWEEN CONVERT(datetime, '20/12/2015', 103)
AND CONVERT(datetime, '22/12/2015', 103);
答案 3 :(得分:0)
检查服务器上的区域设置。我敢打赌,你被设置为美国日期格式,但你在那里的日期不是美国格式。
有关查询区域设置here的详细信息。
This SO question有多种方法可以调整SQL的语言环境设置,包括用户。
如果您无权更改整个服务器的区域设置,则可以在会话here中更改区域设置。请注意,SET LANGUAGE会自动设置DATEFORMAT,但您可以单独set the DATEFORMAT。
要对此进行测试,请尝试撤消日期中的日期和月份。像这样:
SELECT *
FROM QuestionnaireAnswer
WHERE dateCreated BETWEEN CAST('12/20/2015' AS datetime) AND CAST('12/22/2015' AS datetime)
或者尝试将日期放在"locale insensitive format"中,例如yyyymmdd HH:mm:ss.fff。
答案 4 :(得分:-1)
如果列是日期字段,那么您应该这样做:
SELECT *
FROM QuestionnaireAnswer
WHERE dateCreated BETWEEN TO_DATE('20-DEC-2015') AND TO_DATE('22-DEC-2015')
可能不是100%准确,具体取决于架构和配置。