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)\’