我有一个存储过程,我希望在执行时获取reportdate
。
我将一个参数传递给存储过程以执行它。我像这样传递它
exec UserReportData '10-06-2016'
但是我收到了错误:
将char数据类型转换为datetime数据类型会导致日期时间值超出范围。
这是我的存储过程:
ALTER PROCEDURE [dbo].[UserReportData]
@As_ONDATE Datetime
AS
BEGIN
DECLARE @REPORTDATE datetime
--DECLARE @OPENING INT
SELECT *
INTO #temptable
FROM
(SELECT
a.CUser_id, b.User_Id, a.U_datetime AS REPORTDATE
FROM
inward_doc_tracking_trl a, user_mst b
WHERE
a.CUser_id = b.mkey
AND CONVERT(varchar(50), a.U_datetime, 103) = @As_ONDATE) AS x
DECLARE Cur_1 CURSOR FOR
SELECT CUser_id, User_Id
FROM #temptable
OPEN Cur_1
DECLARE @CUser_id INT
DECLARE @User_Id INT
FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT CONVERT(varchar(50), U_datetime, 103)
FROM inward_doc_tracking_trl
WHERE CONVERT(varchar(50), U_datetime, 103) = @As_ONDATE
UPDATE #temptable
SET REPORTDATE = @REPORTDATE
WHERE CUser_id = @CUser_id
AND User_Id = @User_Id
FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id
END
CLOSE Cur_1
DEALLOCATE Cur_1
SELECT * FROM #temptable
DROP TABLE #temptable
END
请帮助我知道错误的原因是什么。
答案 0 :(得分:2)
各种设置(语言,日期格式)仅影响SQL Server Management Studio中向您显示DateTime
的方式 - 或者当您尝试将字符串转换为DateTime
时如何解析它。
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及更高版本。
如果您使用SQL Server 2008或更高版本以及DATE
数据类型(仅DATE
- 不 DATETIME
!),那么您确实也可以使用YYYY-MM-DD
格式,也适用于SQL Server中的任何设置。
不要问我为什么整个主题都是如此棘手而且有点令人困惑 - 这就是它的方式。但是使用YYYYMMDD
格式,您可以适用于任何版本的SQL Server以及SQL Server中的任何语言和日期格式设置。
对于SQL Server 2008及更高版本的建议是,如果您只需要日期部分,则使用DATE
,当需要日期和时间时,使用DATETIME2(n)
。您应该尽可能尝试开始逐步淘汰DATETIME
数据类型
因此,在您的具体案例中 - 只需将您调用存储过程的方式更改为:
exec UserReportData '20160610' -- 10th of June, 2016
或
exec UserReportData '20161006' -- 6th of October, 2016
取决于您是在2016年10月6日还是2016年6月10日,您对此感兴趣...
答案 1 :(得分:0)
您正在传递datetime
,默认情况下,SQL Server使用MMDDYYYY
或YYYYMMDD
格式。
您使用的是DD-MM-YYYY
格式
要么写为
set dateformat dmy --set ddmmyyyy format
exec UserReportData '10-06-2016'
set dateformat mdy --set default again
或者您传递了格式正确的值。没有其他解决方案可以工作。