oracle 创建job 定时调度存储过程

1、建表

create  table test_job(para_date date); 
commit; 

insert into test_job values(sysdate); 
commit; 

select  * from test_job;

2、建立存储过程

create  or replace  procedure test_jobproce as 
begin 
insert into test_job values(sysdate); 
end test_jobproce; 

3、创建job,job创建之后是默认执行的

declare test_job_really  number; 
begin 
 dbms_job.submit(test_job_really,'test_jobproce;',sysdate,'sysdate+1/1440'); 
commit; 
end; 

4、可手动执行和停止执行job

先获取到job的编号:

select  * from sys.user_jobs 

启动job:

begin 
 dbms_job.run(25); 
commit; 
end; 

停止job:

begin 
 dbms_job.broken(25,true);
 commit; 
end; 

删除job:

begin 
 dbms_job.remove(25); 
commit; 
end; 

 项目中的应用:

场景:定时检查表里边的数据,将上个月老人入住产生的固定费用,录入到费用清单中,已经录入的月份,不再录入

CREATE OR REPLACE PROCEDURE proc_fixed_pay_into_listofcost
 AS
 cursor cursor_checkin is select checkout.sys_uid,checkout.id,checkout.pid,checkout.create_date,checkout.fixPay,checkout.cost_fixed,checkout.thismonth from ( SELECT sys_guid() as sys_uid,c.id,c.pid ,c.create_date,c.out_time,(c.sum_cost-c.sum_discount) as fixPay,round((c.sum_cost-c.sum_discount)/(to_number(to_char(last_day(add_months(trunc(sysdate),-1)),'dd')))*
  (case      
  when to_char(c.Create_Date,'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') then  to_char(to_date(c.out_time),'dd')
  when to_char(c.Create_Date,'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') != to_char(sysdate,'yyyymm') then  to_char(last_day(to_date(add_months(trunc(sysdate),-1),'yyyymm')),'dd')
  when to_char(c.Create_Date,'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') then (to_number(to_char(to_date(c.out_time),'dd')) - to_number(to_char(c.Create_Date,'dd'))+1||'')
  when to_char(c.Create_Date,'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') then  (to_number(to_char(add_months(trunc(sysdate),-1),'dd')) - to_number(to_char(c.Create_Date,'dd'))+1||'')
  end),2) as cost_fixed,to_char(add_months(trunc(sysdate),-1),'yyyymm') as thisMonth,(case      
  when to_char(c.Create_Date,'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') then  to_char(to_date(c.out_time),'dd')
  when to_char(c.Create_Date,'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') != to_char(sysdate,'yyyymm') then  to_char(last_day(to_date(add_months(trunc(sysdate),-1),'yyyymm')),'dd')
  when to_char(c.Create_Date,'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') then (to_number(to_char(to_date(c.out_time),'dd')) - to_number(to_char(c.Create_Date,'dd'))+1||'')
  when to_char(c.Create_Date,'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm') and to_char(decode(c.out_time,null,sysdate,c.out_time),'yyyymm') != to_char(add_months(trunc(sysdate),-1),'yyyymm') then  (to_number(to_char(add_months(trunc(sysdate),-1),'dd')) - to_number(to_char(c.Create_Date,'dd'))+1||'')
  end) as tt 
  FROM OLD_CHECKIN c,OLDPERSON op 
  where c.pid = op.id
  and c.chenk_status != '04'--已结算
  and  (c.out_time is null or to_char(c.out_time,'yyyymm') = to_char(add_months(trunc(sysdate),-1),'yyyymm'))  
  and to_char(c.Create_Date,'yyyymm') <=  to_char(add_months(trunc(sysdate),-1),'yyyymm') ) checkout where checkout.tt is not null;
 var_id VARCHAR2(32);--uuid
 var_pid VARCHAR2(32);--pid
 var_create_date date;--老人入住时间
 var_cost_fixed NUMBER(11,2);--老人上个月应扣固定费用
 var_cost NUMBER(11,2);--每月固定费用
 var_checkin_id VARCHAR2(32);--checkinId
 var_this_month VARCHAR2(10);--当前月份
 var_banlance VARCHAR2(20);--当前余额
 var_banlance_count NUMBER(20);--当前入住老人在费用清单列表中的记录数
 var_cost_count NUMBER(20);--当前入住老人在费用清单列表中的本月固定消费的记录数
 BEGIN
 
 --将上个月及上个月之前的入住老人的固定费用添加进费用清单列表
 
 -- 筛选条件  1、退住时间在当月  2、退住时间也不在当月  3、无退住时间
 -- 公共条件  入住时间不在当月
  open cursor_checkin;
  loop
    fetch cursor_checkin into var_id,var_checkin_id,var_pid,var_create_date,var_cost,var_cost_fixed,var_this_month;
    exit when cursor_checkin%notfound;
    
    --需要根据checkinId查询当前入住老人在费用清单中的余额
     select max(balance),count(balance) into var_banlance,var_banlance_count from 
     (select (to_number(decode(lo.banlance,null,'0',lo.banlance)) - to_number(var_cost_fixed))||'' as balance,rownum from list_of_cost lo left join old_checkin ck
             on lo.checkin_id = ck.id 
              where lo.checkin_id = ''||var_checkin_id
              order by lo.create_date desc) 
     where rownum = 1 ;
    
    --表里边如果没有记录,余额就是0减去本次固定费用
    if var_banlance_count=0 then
      var_banlance := '-'||var_cost_fixed;
    end if;

    --如果本月已经插入郭记录,就不再插入 
     select count(id) into var_cost_count from  list_of_cost 
              where checkin_id = ''||var_checkin_id
              and to_char(create_date,'yyyymm') = to_char(sysdate,'yyyymm')
              and fee_id = ''||var_this_month; 
    
    if var_banlance_count < 1 then
        insert into list_of_cost (id,PID,inex_type,wxpend,amount,banlance,remark,create_by,create_date,checkin_id,fee_id)
        values(var_id,var_pid,'02','01',var_cost_fixed,var_banlance,var_this_month||'月固定费用','admin',sysdate,var_checkin_id,var_this_month);
        dbms_output.put_line('var_id:'||var_id||',var_create_date:'||var_create_date||',var_cost:'||var_cost||',var_cost_fixed:'||var_cost_fixed||',var_banlance:'||var_banlance||',var_this_month:'||var_this_month);
    end if;
    
  end loop;
  close cursor_checkin;
  dbms_output.put_line('---loop end---');

COMMIT;
 EXCEPTION
 WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('发生错误,同步失败!');
 ROLLBACK;
 END;

定义job,设定每个月执行一次

---创建job 每个月定时执行一次
declare job_fixed_pay_into_listofcost  number; 
begin 
 dbms_job.submit(job_fixed_pay_into_listofcost,'proc_fixed_pay_into_listofcost;',sysdate, 'TRUNC(LAST_DAY(SYSDATE ) + 1)' ); 
commit; 
end; 

select * from dba_jobs;

关于设定定时任务的参数解析:

描述                    INTERVAL参数值
每天午夜12点            'TRUNC(SYSDATE + 1)'
每天早上8点30分         'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
每星期二中午12点         'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
每个月第一天的午夜12点    'TRUNC(LAST_DAY(SYSDATE ) + 1)'
每个季度最后一天的晚上11点 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
每星期六和日早上6点10分    'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'

原文地址:https://www.cnblogs.com/guo-eric/p/8351523.html