Sql server 2012 在填充日历的存储过程中,从字符串到日期的转换失败
这是我试图用来填充SQL Server中的表的存储过程:Sql server 2012 在填充日历的存储过程中,从字符串到日期的转换失败,sql-server-2012,Sql Server 2012,这是我试图用来填充SQL Server中的表的存储过程: ALTER PROCEDURE [IMM1069].[uspVulKalender] @jaarVanaf varchar(10), @jaarTot varchar(10) AS declare @startdag varchar(20) declare @einddag varchar(20) declare @lopendeDag date = null declare @weekdag bit
ALTER PROCEDURE [IMM1069].[uspVulKalender]
@jaarVanaf varchar(10),
@jaarTot varchar(10)
AS
declare @startdag varchar(20)
declare @einddag varchar(20)
declare @lopendeDag date = null
declare @weekdag bit = 0
set @startdag = '01/01/'+@jaarVanaf
set @einddag = '31/12/'+@jaarTot
BEGIN
set @lopendeDag = cast(@startdag as date)
While @lopendeDag <= cast(@einddag as date)
if datepart(dw,getdate()) = 6 or datepart(dw,getdate()) = 7
set @weekdag = 0
else
set @weekdag = 1
print(@lopendeDag)
insert into [IMM1069].[tbl_kalender](tbl_kalender.datum, tbl_kalender.dag, tbl_kalender.dag_naam, tbl_kalender.isWeekdag, tbl_kalender.week, tbl_kalender.maand, tbl_kalender.maand_naam, tbl_kalender.jaar)
values(
@lopendeDag, --datum
datepart(dw,@lopendeDag), -- weekdaynr
datename(dw,@lopendeDag), -- name day
@weekdag, -- isWeekday
datepart(wk,@lopendeDag), -- weeknr
datepart(mm,@lopendeDag), -- monthnr
datename(mm,@lopendeDag), -- monthname
datepart(yyyy,@lopendeDag)
)
set @lopendeDag = dateadd(dd,1,@lopendeDag)
END
执行存储过程时出现以下错误:
Msg 241,16级,状态1,程序uspVulKalender,第21行
从字符串转换日期和/或时间时,转换失败
提前感谢您的帮助
Jannick您已经将其标记为SQL Server 2012,因此您应该使用全新的FromParts方法。如果是类似日期或时间的项,则有相应的FromParts方法。在你的例子中,你看到的是来自零件的日期 我想Aaraon已经指出,不应该使用字符串来存储日期。考虑到你的非英语源代码,我认为国际化对于其他人来说并不是一个陌生的概念,现在我从我的肥皂盒中退出 你仍然有一个逻辑问题,但我要做的是 将@startdag和@einddag的数据类型更改为date。 不使用字符串连接,而是使用。
您的While循环比较简化为@lopendeDag,这是一种更有效的方法。每当你认为你将得到一堆行,然后一次循环一行,试着换一种方式思考。SQL Server经过优化,可以在集合中工作,而不是在循环中工作。以下是一个基于集合的备选方案:
ALTER PROCEDURE [IMM1069].[uspVulKalender]
@jaarVanaf INT,
@jaarTot INT
AS
BEGIN
SET NOCOUNT ON;
IF @jaarVanaf NOT BETWEEN 2010 AND 2030
OR @jaarTot NOT BETWEEN 2010 AND 2030
BEGIN
RETURN;
END
;WITH n(n) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_columns
), d(d) AS
(
SELECT DATEADD(DAY, n-1, DATEADD(YEAR, @jaarVanaf-1900, 0)) FROM n
WHERE n <= DATEDIFF(DAY, DATEADD(YEAR, @jaarVanaf-1900, 0),
DATEADD(YEAR, @jaarTot-1899, 0))
)
--insert into [IMM1069].[tbl_kalender]
--(datum,dag,dag_naam,isWeekdag,week,maand,maand_naam,jaar)
SELECT
d,
DATEPART(WEEKDAY, d), -- datum
DATENAME(WEEKDAY, d), -- weekdaynr
CASE WHEN DATEPART(WEEKDAY, d) IN (6,7) THEN 0 ELSE 1 END, -- isWeekday
DATEPART(WEEK, d), -- weeknr
DATEPART(MONTH, d), -- monthnr
DATENAME(MONTH, d), -- monthname
DATEPART(YEAR, d) -- yearnr
FROM d;
END
一些注意事项:
传递年份的整数。没有理由在这里传递字符串,然后使用连接来形成区域性的、不明确的日期字符串。
sys.all_columns查询应支持空数据库中约8400行,具体取决于SQL Server的版本。这将让你建立一个跨越23年的日期范围。如果需要更多,可以交叉连接到sys.objects,也可以创建自己的数字表。
insert不需要在每一列上都使用表前缀。我已经注释掉了上面的插入,因此您可以在尝试执行插入之前测试输出。
我已经详细说明了日期部分,而不是使用缩写,因为这些可能会引起混淆。例如,尝试选择DATEPARTY、GETDATE、DATEPARTW、GETDATE;-这会产生你期望的结果吗?
一些背景博文:
调用proc时,您提供了哪些值??为什么一年是一年?你知道有哪一年不是四个字符吗?另外,您的WHILE循环是无限的,我不认为您打算在每一行上插入星期四等-您的代码应该使用变量,而不是GETDATE…@jpw;我在执行存储过程时提供2年的时间,例如2014年为开始年,2015年为结束年。因此,该过程应该从2014年1月1日开始,直到2015年12月31日。嘿,Billinkc,我使用的是SQL Server 2012的快速版本。显然,DATEFROMPARTS函数在此版本中不是内置的,因为我在执行存储过程时遇到以下错误:DATEFROMPARTS不是可识别的函数名。但是Aaron已经解决了这个问题。谢谢你的努力!GrJannick@GrJannick您确定正在使用SQL Server 2012吗?选择什么@版本;说我打赌您使用的是2012 SSMS,但连接的是较旧的发动机。
ALTER PROCEDURE [IMM1069].[uspVulKalender]
@jaarVanaf INT,
@jaarTot INT
AS
BEGIN
SET NOCOUNT ON;
IF @jaarVanaf NOT BETWEEN 2010 AND 2030
OR @jaarTot NOT BETWEEN 2010 AND 2030
BEGIN
RETURN;
END
;WITH n(n) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_columns
), d(d) AS
(
SELECT DATEADD(DAY, n-1, DATEADD(YEAR, @jaarVanaf-1900, 0)) FROM n
WHERE n <= DATEDIFF(DAY, DATEADD(YEAR, @jaarVanaf-1900, 0),
DATEADD(YEAR, @jaarTot-1899, 0))
)
--insert into [IMM1069].[tbl_kalender]
--(datum,dag,dag_naam,isWeekdag,week,maand,maand_naam,jaar)
SELECT
d,
DATEPART(WEEKDAY, d), -- datum
DATENAME(WEEKDAY, d), -- weekdaynr
CASE WHEN DATEPART(WEEKDAY, d) IN (6,7) THEN 0 ELSE 1 END, -- isWeekday
DATEPART(WEEK, d), -- weeknr
DATEPART(MONTH, d), -- monthnr
DATENAME(MONTH, d), -- monthname
DATEPART(YEAR, d) -- yearnr
FROM d;
END