1

我有一个存储过程,它接受一个作为字符串传入的日期时间参数。比如这样:

程序:

CREATE PROCEDURE [dbo].[MyFancySP]
   @MyStartDate datetime = NULL,
   @MyEndDate datetime = NULL
AS
....

称呼:

EXEC [dbo].[MyFancySP]
   @MyStartDate = N'01/01/2012',
   @MyEndDate = N'03/01/2012'

存储过程一直这样工作。现在,这是有趣的部分。一旦我将日期更改为 2012 年 3 月 27 日或过去,我就会收到以下错误:将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。

存储过程中唯一使用日期的地方是 where 子句。如果它与它有关,我也会在这里复制它:

WHERE
((@MyStartDate IS NOT NULL AND @MyEndDate IS NOT NULL 
AND d.SomeDate >= @MyStartDate AND d.SomeDate <= @MyEndDate) 
OR @MyStartDate IS NULL AND @MyEndDate IS NULL)

任何想法为什么我会在 3 月 27 日或之后得到超出范围的异常?顺便说一下,这是在 SQL Server 2008 R2 上运行的。

谢谢!

4

2 回答 2

2

在每个新的数据库连接上执行以下操作。

SET DATEFORMAT DMY

完成此操作后,您的问题应该会消失。我怀疑您的问题是由服务器语言环境的组合决定的,以及一个月中的日期是否是 13 日到 31 日。

您不仅会看到错误,还可能会在不注意的情况下获取不正确时期的数据;您的软件的其他层可能会对此进行纠正,但可能仅在某些情况下。

于 2012-04-19T16:28:58.883 回答
1

什么类型d.SomeDate?这是一个NVARCHAR偶然的机会吗?这可以解释它,因为在这种情况下,WHERE 子句将包含一个隐式转换,即数据类型优先级的规则状态应该作为DATETIME. 错误的明显随机性是由于查询扫描字段中具有无效日期的行这一简单事实d.SomeDate。在这种情况下,您正在处理数据纯度问题,您应该修复您的表,最好将列设置为 DATETIME。

此外:

  • YYYYMMMDD始终在字符串表示中使用规范的日期格式(无分隔符): EXEC [dbo].[MyFancySP] N'20120101', N'20120301';. 此格式与主机区域设置、DATEFORMAT 和 LANGUAGE 设置无关,.

  • 阅读T-SQL 中的动态搜索条件WHERE column=@value or @value is null停止查询性能优化死在其轨道上。阅读文章。

于 2012-04-19T17:40:43.173 回答