1

我正在制作一个使用 Windows 调度程序自动运行的程序。我想做的是将程序设置为在每个月的 1 日和 16 日运行。如果程序运行在 1 日。我想运行上个月的查询...例如,如果今天是 8 月 1 日,我希望它在 2012 年 7 月 1 日至 2012 年 7 月 31 日运行。如果我在 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
4

4 回答 4

3

尝试8/1/20128/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

调整这一点相当容易,以便它可以根据任何输入日期动态计算正确的开始日期和结束日期——这样你就可以在一个月内的任何时候运行它。

于 2012-08-06T18:15:30.880 回答
2

这应该很简单,让我为您举一些例子。我真的认为这应该是一个预定任务,而不是多个。在一天结束时,更容易指出并查看一项计划任务(一个程序),然后去挖掘多个程序,看看可能有什么问题。

可以使用 SQL Server 代理(在作业部分下)安排任务。该作业可以指向一个存储过程。

在程序中你可以做一个简单的if else if逻辑。

IF DAY(GetDate()) = 1 --代码在这里

ELSE IF DAY(GETDATE()) = 16 --代码在这里

DAY(date_expression) 返回日期时间列中的日期。具有讽刺意味的是,如果您出于某种原因需要这些功能,则存在 MONTH 和 YEAR 功能。其余的很简单,如果您在该月的第一个日期,则从第一个日期到下个月的第一个日期执行每月查询 - 1,这将变为:

SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))

否则如果到了16号,你可以在第一天跑到半个月。

于 2012-08-06T18:15:42.767 回答
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
    )
于 2012-08-06T18:31:24.973 回答
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所需的两个值。在您的选择语句中放置占位符(“@dtFrom”和“@dtThru”)。执行查询时,将两个DateTime值作为名称与占位符匹配的 SqlParameter 对象传递。

于 2012-08-07T00:06:24.990 回答