1

Windowsスケジューラを使用して自動実行するプログラムを作成しています。私がやりたいことは、プログラムを毎月 1 日と 16 日に実行するように設定することです。プログラムが最初に実行された場合。先月のクエリを実行したいのですが... たとえば、今日が 8 月 1 日の場合、2012 年 7 月 1 日から 2012 年 7 月 31 日まで実行したいと思います。16 日にプログラムを実行する場合、当月から 15 日にクエリを実行する必要があります。たとえば、8/16 の場合、プログラムで 8/1/12 から 8/15/12 のクエリを実行する必要があります。これを達成するための最良の方法は何ですか?クエリを正しい日付範囲に関連付けて、2 つの別々のプログラムを使用する必要がありますか? 1 つは毎月 1 日、もう 1 つは 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

これは簡単なはずです。いくつかの例を紹介しましょう。これは複数のタスクではなく、1 つのスケジュールされたタスクであるべきだと本当に思います。1 日の終わりに、スケジュールされた 1 つのタスク (1 つの手順) を指して確認し、複数の手順を掘り下げて、何が間違っていなかったのかを確認する方が簡単です。

タスクは、SQL Server エージェント (ジョブ セクションの下) を使用してスケジュールできます。ジョブは、1 つのストアド プロシージャを指すことができます。

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日に当たれば月の半分まで初日から出走可能。

于 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

ストアド プロシージャを使用していない場合は、パラメーター化されたクエリを使用して同じことを行うことができます。必要な2 つの値を計算しDateTimeます。select ステートメントにプレースホルダーを入れます ('@dtFrom' および '@dtThru')。クエリを実行するときはDateTime、プレースホルダーに一致する名前を持つ SqlParameter オブジェクトとして 2 つの値を渡します。

于 2012-08-07T00:06:24.990 に答える