执行存储过程导致错误
Executing the stored procedure causes error
我有一个存储过程,我想在其中执行时获取 reportdate
。
我将一个参数传递给存储过程来执行它,。我是这样传的
exec UserReportData '10-06-2016'
但我得到一个错误:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
这是我的存储过程:
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
请帮助我知道错误的原因。
各种设置(语言、日期格式)仅影响 DateTime
在 SQL Server Management Studio 中的显示方式 - 或者当您尝试将字符串转换为一个DateTime
。
SQL 服务器支持多种格式 - 请参阅 MSDN Books Online on CAST
and CONVERT
。大多数这些格式依赖于您的设置 - 因此,这些设置有时可能有效 - 有时无效。
解决这个问题的方法是使用 SQL 服务器支持的(稍微改编的)ISO-8601 日期格式 - 这种格式有效 始终 - 无论您的 SQL 服务器语言和日期格式设置如何。
ISO-8601 format 受 SQL 支持 服务器有两种形式:
YYYYMMDD
仅用于日期(无时间部分);此处注意:没有破折号!,这一点非常重要! YYYY-MM-DD
NOT 独立于 SQL 服务器中的日期格式设置,并且 NOT 在所有情况下都有效!
或:
YYYY-MM-DDTHH:MM:SS
用于日期和时间 - 请注意:此格式 有 破折号(但它们 可以 被省略),和一个固定的 T
作为 DATETIME
. 的日期和时间部分之间的分隔符
这对 SQL Server 2000 及更新版本有效。
如果您使用 SQL Server 2008 或更新版本和 DATE
数据类型(仅 DATE
- 而非 DATETIME
! ),那么您确实也可以使用 YYYY-MM-DD
格式,这也适用于您 SQL 服务器中的任何设置。
不要问我为什么整个主题如此棘手和令人困惑 - 就是这样。但是使用 YYYYMMDD
格式,对于任何版本的 SQL 服务器以及 SQL 服务器中的任何语言和日期格式设置都应该没问题。
对于 SQL Server 2008 和更新版本的建议是,如果您只需要日期部分,则使用 DATE
,如果您需要日期和时间,则使用 DATETIME2(n)
。如果可能的话,您应该尝试开始逐步淘汰 DATETIME
数据类型
因此,在您的具体情况下 - 只需将调用存储过程的方式更改为:
exec UserReportData '20160610' -- 10th of June, 2016
或
exec UserReportData '20161006' -- 6th of October, 2016
取决于您感兴趣的日期是 2016 年 10 月 6 日还是 6 月 10 日...
您正在传递 datetime
,默认情况下 SQL 服务器使用 MMDDYYYY
或 YYYYMMDD
格式。
您正在使用 DD-MM-YYYY
格式,
要么你写成
set dateformat dmy --set ddmmyyyy format
exec UserReportData '10-06-2016'
set dateformat mdy --set default again
或者您传递了格式正确的值。没有其他解决方案。
我有一个存储过程,我想在其中执行时获取 reportdate
。
我将一个参数传递给存储过程来执行它,。我是这样传的
exec UserReportData '10-06-2016'
但我得到一个错误:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
这是我的存储过程:
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
请帮助我知道错误的原因。
各种设置(语言、日期格式)仅影响 DateTime
在 SQL Server Management Studio 中的显示方式 - 或者当您尝试将字符串转换为一个DateTime
。
SQL 服务器支持多种格式 - 请参阅 MSDN Books Online on CAST
and CONVERT
。大多数这些格式依赖于您的设置 - 因此,这些设置有时可能有效 - 有时无效。
解决这个问题的方法是使用 SQL 服务器支持的(稍微改编的)ISO-8601 日期格式 - 这种格式有效 始终 - 无论您的 SQL 服务器语言和日期格式设置如何。
ISO-8601 format 受 SQL 支持 服务器有两种形式:
YYYYMMDD
仅用于日期(无时间部分);此处注意:没有破折号!,这一点非常重要!YYYY-MM-DD
NOT 独立于 SQL 服务器中的日期格式设置,并且 NOT 在所有情况下都有效!
或:
YYYY-MM-DDTHH:MM:SS
用于日期和时间 - 请注意:此格式 有 破折号(但它们 可以 被省略),和一个固定的T
作为DATETIME
. 的日期和时间部分之间的分隔符
这对 SQL Server 2000 及更新版本有效。
如果您使用 SQL Server 2008 或更新版本和 DATE
数据类型(仅 DATE
- 而非 DATETIME
! ),那么您确实也可以使用 YYYY-MM-DD
格式,这也适用于您 SQL 服务器中的任何设置。
不要问我为什么整个主题如此棘手和令人困惑 - 就是这样。但是使用 YYYYMMDD
格式,对于任何版本的 SQL 服务器以及 SQL 服务器中的任何语言和日期格式设置都应该没问题。
对于 SQL Server 2008 和更新版本的建议是,如果您只需要日期部分,则使用 DATE
,如果您需要日期和时间,则使用 DATETIME2(n)
。如果可能的话,您应该尝试开始逐步淘汰 DATETIME
数据类型
因此,在您的具体情况下 - 只需将调用存储过程的方式更改为:
exec UserReportData '20160610' -- 10th of June, 2016
或
exec UserReportData '20161006' -- 6th of October, 2016
取决于您感兴趣的日期是 2016 年 10 月 6 日还是 6 月 10 日...
您正在传递 datetime
,默认情况下 SQL 服务器使用 MMDDYYYY
或 YYYYMMDD
格式。
您正在使用 DD-MM-YYYY
格式,
要么你写成
set dateformat dmy --set ddmmyyyy format
exec UserReportData '10-06-2016'
set dateformat mdy --set default again
或者您传递了格式正确的值。没有其他解决方案。