定期运行Oracle查询的最佳方法

jab*_*lab 1 oracle oracle11g

我需要知道在Oracle上定期运行查询的最佳实践是什么(我使用的是11g).

在我的特定用例中,我DUE_DATE在表中指定了一个x.我想要做的是每天00:01运行一个查询来计算某些记录的状态(OK,Warn,Critical或Overdue).特定记录的状态是从今天的日期(其中"今天"是查询运行的那天)相对于x.DUE_DATE和某些用户指定的值来计算的,这些值表示"警告"和"严重"(包含在表中y).

  • 好的 - > today < x.DUE_DATE - y.WARN
  • 警告 - > today >= x.DUE_DATE - y.WARN and today < x.DUE_DATE - y.CRITICAL
  • 关键 - > today >= x.DUE_DATE - y.CRITICAL and today <= x.DUE_DATE
  • 逾期 - > today > x.DUE_DATE

定期运行此查询的最佳方法是什么?我找到了以下选项但不确定哪个最适合我的用例:

我知道我可以根据每个用户请求动态计算状态,但由于停顿只会每天更改一次,我认为进行计算会更有效,并且每天也会缓存一次后续结果.

提前谢谢了.

GWu*_*GWu 9

  • 对于运行作业(和查询),DBMS_SCHEDULER是可供选择的工具.因此,如果要根据查询结果更新表中的状态,请使用DBMS_SCHEDULER.

例如,您可以安排执行以下更新的作业:

update x
   set status = (CASE 
                   WHEN sysdate < x.DUE_DATE - y.WARN THEN
                     'Ok'
                   WHEN sysdate >= x.DUE_DATE - y.WARN and today < x.DUE_DATE - y.CRITICAL THEN
                     'Warn'
                   WHEN sysdate >= x.DUE_DATE - y.CRITICAL and sysdate <= x.DUE_DATE THEN
                     'Critical'
                   WHEN sysdate > x.DUE_DATE THEN
                     'Overdue'
                 END)
;
Run Code Online (Sandbox Code Playgroud)

要创建每天00:00安排的作业:

BEGIN
    dbms_scheduler.create_job(job_name => 'Status Updater',
                              job_type => 'PLSQL_BLOCK',
                              job_action => '
                                             BEGIN 
                                              update x
                                                set status = (CASE 
                                                                WHEN sysdate < x.DUE_DATE - y.WARN THEN
                                                                  ''Ok''
                                                                WHEN sysdate >= x.DUE_DATE - y.WARN and today < x.DUE_DATE - y.CRITICAL THEN
                                                                  ''Warn''
                                                                WHEN sysdate >= x.DUE_DATE - y.CRITICAL and sysdate <= x.DUE_DATE THEN
                                                                  ''Critical''
                                                                WHEN sysdate > x.DUE_DATE THEN
                                                                  ''Overdue''
                                                              END)
                                                 ;
                                              END;',
                              start_date => systimestamp,
                              repeat_interval => 'FREQ=DAILY;INTERVAL=1;BYHOUR=0;BYMINUTE=0;',
                              enabled => TRUE);
END;
/
Run Code Online (Sandbox Code Playgroud)
  • 如果需要准备报告,请在报告工具中计划报告,或使用物化视图存储结果集.