我正在尝试编写一个存储过程,该过程将在每月的1日,8日,15日和22日由自动报告调用。
下面我有我目前正在尝试使用的代码,但如果在第一天运行,我会在@StartDate的行上收到错误Explicit conversion from data type int to date is not allowed.
。但是我已经尝试评论该部分,我只是得到了相同的错误,但接下来是@StartDate。
我需要@StartDate和@EndDate才能根据当前运行报告的哪一天进行更改。
在22日,它必须是当月到21日的第15个。
Declare @RunDate date
Declare @StartDate Date
Declare @EndDate Date
Set @RunDate = '3/1/2017'
If (Day(@RunDate) = 1)
Begin
Set @StartDate = Convert(Date,(Month(DATEADD(d,-1,@Rundate)) + '/21/' + Case When Month(@Rundate) = '1' Then Year(@RunDate) Else Year(DATEADD(yy,-1,@Rundate)) End),101)
Set @EndDate = Convert(date,DATEADD(ms,-3,DATEADD(mm,0,DATEADD(mm,DATEDIFF(mm,0,@Rundate),0))),101)
End
Else
IF (Day(@RunDate) = 8)
Begin
Set @StartDate = Convert(Date,(Month(@Rundate) + '/1/' + Year(@RunDate)),101)
Set @EndDate = Convert(Date,(Month(@Rundate) + '/7/' + Year(@RunDate)),101)
End
Else
If (Day(@Rundate) = 15)
Begin
Set @StartDate = Convert(Date,(Month(@Rundate) + '/8/' + Year(@RunDate)),101)
Set @EndDate = Convert(Date,(Month(@Rundate) + '/14/' + Year(@RunDate)),101)
End
Else
If (Day(@Rundate) = 22)
Begin
Set @StartDate = Convert(Date,(Month(@Rundate) + '/15/' + Year(@RunDate)),101)
Set @EndDate = Convert(Date,(Month(@Rundate) + '/21/' + Year(@RunDate)),101)
End
我正在使用带有SSMS 2016前端的SQL Server 2012后端。如果这有帮助。
答案 0 :(得分:2)
您可以将所有这些简化为:
Declare @RunDate date, @StartDate date, @EndDate date;
Set @RunDate = '20170301';
If (Day(@RunDate) = 1)
Begin;
Set @StartDate = dateadd(day,20,dateadd(month, datediff(month, 0, @RunDate)-1, 0))
Set @EndDate = dateadd(day,-1,dateadd(month, datediff(month, 0, @RunDate), 0))
End;
Else
If (Day(@RunDate) in (8,15,22))
Begin;
Set @StartDate = dateadd(day,Day(@RunDate)-8,dateadd(month, datediff(month, 0, @RunDate), 0))
Set @EndDate = dateadd(day,Day(@RunDate)-2,dateadd(month, datediff(month, 0, @RunDate), 0))
End;
使用case
替代,但不验证day()
中的8,15,22
:
Declare @RunDate date, @StartDate date, @EndDate date;
Set @RunDate = '20170328';
set @StartDate = case day(@RunDate)
when 1 then dateadd(day,20,dateadd(month, datediff(month, 0, @RunDate)-1, 0))
else dateadd(day,Day(@RunDate)-8,dateadd(month, datediff(month, 0, @RunDate), 0))
end;
set @EndDate = case day(@RunDate)
when 1 then dateadd(day,-1,dateadd(month, datediff(month, 0, @RunDate), 0))
else dateadd(day,Day(@RunDate)-2,dateadd(month, datediff(month, 0, @RunDate), 0))
end;
两者的rextester演示:http://rextester.com/CCUFI85069
答案 1 :(得分:0)
尝试更改代码以设置日期......
SET @StartDate = CONVERT(DATE,
CONCAT(MONTH(DATEADD(d, -1, @Rundate)),
'/21/',
IIF(MONTH(@Rundate) = '1', YEAR(@RunDate), YEAR(DATEADD(yy, -1, @Rundate)))) , 101)
完整的代码看起来像这样......
Declare @RunDate date
Declare @StartDate Date
Declare @EndDate Date
Set @RunDate = '3/1/2017'
If (Day(@RunDate) = 1)
Begin
Set @StartDate = CONVERT(DATE, CONCAT(MONTH(DATEADD(d, -1, @Rundate)), '/21/',IIF(MONTH(@Rundate) = '1', YEAR(@RunDate), YEAR(DATEADD(yy, -1, @Rundate)))) , 101)
Set @EndDate = Convert(date,DATEADD(ms,-3,DATEADD(mm,0,DATEADD(mm,DATEDIFF(mm,0,@Rundate),0))),101)
End
Else
IF (Day(@RunDate) = 8)
Begin
Set @StartDate = Convert(Date, CONCAT(Month(@Rundate) , '/1/' , Year(@RunDate)) ,101)
Set @EndDate = Convert(Date, CONCAT(Month(@Rundate) , '/7/' , Year(@RunDate)) ,101)
End
Else
If (Day(@Rundate) = 15)
Begin
Set @StartDate = Convert(Date, CONCAT(Month(@Rundate) , '/8/' , Year(@RunDate)) ,101)
Set @EndDate = Convert(Date, CONCAT(Month(@Rundate) , '/14/' , Year(@RunDate)) ,101)
End
Else
If (Day(@Rundate) = 22)
Begin
Set @StartDate = Convert(Date, CONCAT(Month(@Rundate) , '/15/' , Year(@RunDate)) ,101)
Set @EndDate = Convert(Date, CONCAT(Month(@Rundate) , '/21/' , Year(@RunDate)) ,101)
END
SELECT @StartDate, @EndDate
你甚至可以隐藏重复的代码并创建一个简单的函数......
CREATE FUNCTION [dbo].[GetDateBasedOnStringNumber] (@num NVARCHAR(20), @RunDate DATE)
RETURNS DATE
WITH SCHEMABINDING AS
BEGIN
DECLARE @retDate DATE
SELECT @retDate = Convert(Date, CONCAT(Month(@RunDate) , @num , Year(@RunDate)) ,101)
RETURN @retDate ;
END;
然后使用这种模式......
SELECT @StartDate = dbo.GetDateBasedOnStringNumber('/1/', @RunDate)
SELECT @EndDate = dbo.GetDateBasedOnStringNumber('/7/', @RunDate)
答案 2 :(得分:0)
该错误是因为您尝试将integer
和varchar
值一起添加。以此行为例:
Set @StartDate = Convert(Date,(Month(DATEADD(d,-1,@Rundate)) + '/21/' + Case When Month(@Rundate) = '1' Then Year(@RunDate) Else Year(DATEADD(yy,-1,@Rundate)) End),101)
如果您细分计算的部分,则会有integer
个月的值,一天varchar
值和一年integer
值。如果您尝试连接这些,则会收到错误消息:
消息245,级别16,状态1,行9转换时转换失败 varchar值' / 21 /'数据类型int。
您可以将integer
值转换为varchar
,这样就可以了。
建议使用内置的date
函数而不是使用连接,这样就可以获得相同的结果:
DECLARE
@RunDate DATE = '20170101'
, @StartDate DATE
, @EndDate DATE
IF DATEPART(DAY, @RunDate) = 1
SELECT
@StartDate = DATEADD(DAY, -(DATEPART(DAY, DATEADD(DAY, -1, @RunDate)) - 20), @RunDate)
, @EndDate = DATEADD(DAY, -1, @RunDate)
SELECT
@StartDate
, @EndDate