我正在制作一个使用Windows调度程序自动运行的程序。我想做的是将程序设置为在每个月的1日和16日运行。如果程序在1日运行。我想让查询在上个月运行...例如,如果今天是8月的第一个,我希望它运行7/1/12 - 7/31/12。如果我在16日运行该程序,我希望它将当前月份的查询运行到15日。例如,如果是8/16,我希望程序运行8/1/12 - 8/15/12的查询。完成此任务的最佳方法是什么?我是否使用2个单独的程序将查询附加到正确的日期范围?一个计划在每个月的第一天运行,一个在16日运行?我如何获得日期范围和年份,因为它取决于它运行的月份/年...我的查询是:
SELECT Store_Number, Invoice_Number, Invoice_Date, Extended_Price, Warranty_Amount, Quantity_Sold, Invoice_Detail_Code
FROM Invoice_Detail_Tb
WHERE (Warranty_Amount > 0) AND (Invoice_Date BETWEEN CONVERT(DATETIME, '2012-08-01 00:00:00', 102) AND CONVERT(DATETIME, '2012-08-05 00:00:00', 102))
ORDER BY Store_Number, Invoice_Date
答案 0 :(得分:3)
尝试8/1/2012
和8/16/2012
作为日期。它返回您想要查看的值:
declare @date datetime = '8/16/2012', @start datetime, @end datetime
if datepart(dd, @date) = 1
begin
set @start = dateadd(mm, -1, @date)
set @end = dateadd(dd, -1, @date)
end
else
begin
set @start = dateadd(dd, -15, @date)
set @end = dateadd(dd, -1, @date)
end
select @start, @end
调整它可以相当容易,以便根据任何输入日期动态计算正确的开始和结束日期 - 这样您就可以在月份的任何时间运行它。
答案 1 :(得分:2)
这应该很简单,让我为你举一些例子。 我真的认为这应该是一个预定的任务,而不是多个任务。 在一天结束时更容易指出并查看一个计划任务(一个程序) 然后去挖掘多个程序,看看可能有什么不对。
可以使用SQL Server代理(在作业部分下)安排任务。该作业可以指向一个存储过程。
在此过程中,您可以执行简单的if else if
逻辑。
IF DAY(GetDate()) = 1
- 在这里编码
ELSE IF DAY(GETDATE()) = 16
- 在这里编码
DAY(date_expression)返回datetime列中的日期。具有讽刺意味的是,如果由于某种原因需要那些功能,则有MONTH和YEAR功能。其余的很简单,如果你是在这个月的第一个日期,然后执行每月查询从几个月的第一天到下个月的第一天 - 1,这将成为:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
否则,如果它在16日命中,你可以在第一天运行,直到月份的一半。
答案 2 :(得分:1)
如果您在视图中有查询,可以使用:
where
Invoice_Date between
(
case
when datepart(dd, getdate()) = 1 then dateadd(mm, -1, getdate())
else dateadd(dd, -15, getdate())
end
)
and
(
case
when datepart(dd, getdate()) = 1 then dateadd(dd, -1, getdate())
else dateadd(dd, -1, getdate())
end
)
更新:忽略时间
(我知道它看起来很难看。)
where
Invoice_Date between
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(mm, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -15, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
and
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
答案 3 :(得分:0)
这就是我通常做的事情。您的存储过程应如下所示:
declare
@today datetime ,
@dtFrom datetime ,
@dtThru datetime
------------------------------------------------------
-- get the current date, discarding the time component
------------------------------------------------------
set @today = convert(datetime,convert(varchar,current_timestamp,112),112) -- get todays date, discarding the time component
---------------------------------------------------------------------------------------------------------------------------------------------------
-- determine the start/end dates of the query period.
--
-- if the query date (@today) is in the 1st half of the month (1st - 15th), the query range is the entire preceding month
-- if the query date (@today) is in the last half of the month (16 - 31st), the query range is the 1st of the current month up to the current date
---------------------------------------------------------------------------------------------------------------------------------------------------
if ( datepart(day) < 16 )
begin
set @dtThru = dateadd(day, - datepart(day, @today ) , @today ) -- set the end date to the last day of the previous month
set @dtFrom = dateadd(day, 1 - datepart(day, @dtThru ) , @dtThru ) -- set the start date to the first day of the previous month
end
else
begin
set @dtfrom = dateadd(day, 1 - datepart(day, @today) , @today ) -- set the start date to the first day of the current month
set @dtThru = @today
end
----------------------------------------------------------------------------------------------------------------------
-- finally, adjust the start/end times to cover the entire gamut of date/time values for the month
--
-- We don't have to modify @dtFrom at all: we know its time component is 00:00:00.000 already. However, we want
-- @dtThru to have a time component of 23:59:59.997, due to SQL Server's broken way of counting time -- any time value
-- higher than that (e.g., '23:59.59.999') is 'rounded up' to start-of-day (00:00.00.000), the next day. Brilliant!
--
----------------------------------------------------------------------------------------------------------------------
set @dtThru = dateadd(ms, -3 , dateadd(day,1,@dtThru) )
--------------------------------
-- return the data to the caller
--------------------------------
SELECT Store_Number ,
Invoice_Number ,
Invoice_Date ,
Extended_Price ,
Warranty_Amount ,
Quantity_Sold ,
Invoice_Detail_Code
FROM Invoice_Detail_Tb id
WHERE Warranty_Amount > 0
AND Invoice_Date BETWEEN @dtFrom AND @dtThru
ORDER BY Store_Number ,
Invoice_Date
如果您没有使用存储过程,则可以使用参数化查询完成相同的操作。计算所需的两个DateTime
值。将占位符放在select语句中('@ dtFrom'和'@dtThru')。执行查询时,将两个DateTime
值作为SqlParameter对象传递,其名称与占位符匹配。