2

このモデルを考えると:sysschedules、そして再発パターンのさまざまな組み合わせでDBにいくつかのイベントがあったと仮定します:毎日、3日ごとに毎日、毎週火曜日。2週間ごと、28日に毎月、2か月ごとの第2火曜日に毎月、2月28日に毎年など...

与えられたモデルでは、すぐに頭に浮かぶ特定のフィールドがあります。

  • freq_typeを使用して、偶数が日次、週次、月次などであるかどうかを取得します。
  • freq_typeに基づいて間隔を決定するfreq_interval
  • freq_relative_intervalは、イベントが月の1日、2日、3日などにあるかどうかを判別します。
  • freq_recurrence_factorを使用して、イベント発生間の週次/月次の間隔を決定します

今日、2012年2月28日火曜日のすべてのイベントを照会したい場合...それはどのようになりますか?

更新 これまでに思いついたものは次のとおりです(この例では、2月28日に発生するすべての「イベント」(火曜日)が必要です)。 SELECT * FROM TableName WHERE (freq_type = 1 && active_start_date = '2012-02-28') OR (freq_type = 4) OR (freq_type = 8 && freq_interval = 4) OR (freq_type = 32 && freq_interval = 3 && freq_relative_interval = 16)

  • freq_typeが1の場合は、それが1回だけであることを意味し、active_start_dateまでに取得します
  • freq_type 4は毎日を意味し、この日に発生するため、すべてを取得します
  • freq_type 8は毎週を意味し、freq_interval 4でそれらのイベントを取得します(火)
  • freq_type 32は、月次、相対を意味します-freq_interval 3(火)、最後のfreq_relative_interval 16

これがすぐに「間違った」と頭に浮かぶものです

1.毎週火曜日を含め、1日を超えるイベントはどうですか?たとえば、毎週火/木に発生するイベントのfreq_intervalは20になります。火になる可能性のあるfreq_intervalのすべての可能な組み合わせを考慮して、上記のクエリをどのように書き直しますか?

2. n週間/月ごとに発生するイベントはどうですか?今週/月の「オンまたはオフ」の時間枠であるかどうかをどのように知ることができますか?

4

3 に答える 3

4

システムテーブルsysjobschedulesには、ジョブがいつ実行されたか、および次に実行される日時に関する情報が含まれています。これを使用して、特定の日にジョブがいつ実行されるかを見つけることができる場合があります。

問題がないわけではありません。日付は整数として保存され、有用になる前に変換する必要があり、情報はジョブステップが完了した後にのみ更新されます。したがって、少なくとも1回実行されたジョブの結果のみが返されます。

この情報は、 SQLServerエージェントジョブ情報のクエリページのSQLServerエージェントジョブ実行情報セクションから見つけました。

また、MSDNページの下部には、日付をデコードするために使用できる整数から日時を取得するためのUDFを提供するコミュニティコンテンツがいくつかあります。

アップデート

問題について考え、モデルを使用するだけでなく複製しようとしていることに気付いた後sysschedules、答えを更新する必要があると思いました。

あなたは尋ねました:

火になる可能性のあるfreq_intervalのすべての可能な組み合わせを説明するために、上記のクエリをどのように書き直しますか?

日のビットマスク値を使用してテーブルを作成し、それをスケジュールテーブルに結合しました

CREATE TABLE [dbo].[Schedule_Day](
    [day_name] [nchar](10) NOT NULL,
    [day_bit_value] [varbinary](50) NOT NULL
) ON [PRIMARY]

INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Sunday', 1)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Monday', 2)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Tuesday', 4)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Wednesday', 8)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Thursday', 16)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Friday', 32)
INSERT Schedule_Day(day_name, day_bit_value) VALUES ('Saturday', 64)

SELECT Schedule.schedule_id, Schedule.start_date, Schedule_Day.day_name
FROM Schedule INNER JOIN Schedule_Day 
    ON Schedule.freq_interval & Schedule_Day.day_bit_value > 0

火曜日と木曜日に実行されるスケジュールの結果は次のとおりです。

schedule_id freq_type freq_interval freq_recurrence_factor start_date
----------- --------- ------------- ---------------------- ----------
          1        32            20                      1 2012-03-06

schedule_id  start_date  day_name
-----------  ----------  --------
          1  2012-03-06  Tuesday   
          1  2012-03-06  Thursday

ただし、難しい部分は、将来のすべての火曜日と木曜日を月間隔で取得するために、今後の日付を推定することです。それは私があなたに任せる練習です:)

私は以前に、ほぼ同じくらい優れたソリューションを提供するために使用できる可能性のある簡略化されたスケジュールシステムを作成しました。複数のスケジュールエントリを何らかの方法でグループ化することにより、火曜日と木曜日に実行されるスケジュールをシミュレートできます。

私のスケジュール設計にはactive_on_day、スケジュールの実行が許可された曜日を示すフィールドが含まれていたため、job複数のスケジュールを参照すると、それらの日に実行されます。興味があれば、テーブルのデザインとストアドプロシージャを投稿できます。

于 2012-02-14T16:19:25.027 に答える
3

読み取り可能な形式でスケジュールを返すsp_get_schedule_descriptionと呼ばれるプロシージャがあります。プロシージャのすべてのパラメータは、sysschedulesテーブルにあります。

したがって、たとえば、次の情報を持つ「MySchedule1」というスケジュールを作成しました。

Recuring
Weekly
Every 2 weeks
On tuesday
Overy 12 hours Starting at 3 AM enging at 9 PM
from 1/3/2012

私が実行した場合

select 
freq_type, 
freq_interval,  
freq_subday_type, 
freq_subday_interval, 
freq_relative_interval,  
freq_recurrence_factor, 
active_start_date, 
active_end_date,  
active_start_time, 
active_end_time
from sysschedules where name='My Schedule1'

それは私に与えます

freq_type                     8
freq_interval                 5
freq_subday_type              8
freq_subday_interval          12
freq_relative_interval        0
freq_recurrence_factor        2
active_start_date             20120301          
active_end_date               99991231        
active_start_time             30000             
active_end_time               210000

これらの値を次のようにsp_get_schedule_descriptionに入れると、次のようになります。

declare @schedule_description NVARCHAR(255)
exec sp_get_schedule_description 8, 5, 8, 12, 0, 2, 20120301, 99991231, 30000, 210000, @schedule_description output
select @schedule_description

読み取り可能な形式でスケジュールを取得します。

Every 2 week(s) on Sunday, Tuesday every 12 hour(s) between 30000 and 210000

問題は、一度に1つのスケジュールが必要になることです。そのため、ジョブごとに1回呼び出すためのある種のループを考え出し、例の一時テーブルに説明を入れて、次のようなパラメーターを使用して一時テーブルにクエリを実行する必要があります。 1:1:

select * 
from your_table 
where description like '%Tuesday%'
于 2012-03-01T21:47:54.320 に答える
1

完全にテストできませんでした。これはすべての可能性を網羅しているわけではありません。たとえば、イベントが3日ごとに発生する場合、日付や曜日などの計算を行う必要があります。

SELECT     * 
FROM       msdb.dbo.sysschedules 
WHERE   (active_start_date = 20120228) 
    OR (freq_type = 4 AND freq_interval = 1)  --every day
    OR (freq_type = 4 AND freq_interval = 14 AND datename(dw, convert(datetime, convert(varchar(8), active_start_date), 112)) = 'Tuesday') --every 14 days, starting on a Tuesday
        OR (freq_type = 8 AND ((freq_interval & 4) = 4))  -- every Tuesday
        OR (freq_type = 16 AND freq_interval = 28) -- every month on the 28th
        OR (freq_type = 32 AND freq_interval = 3 
            AND (freq_relative_interval = 8 OR freq_relative_interval = 16))  -- monthly on a Tuesday of the Fourth or Last week
于 2012-03-06T18:25:35.483 に答える