存储过程报错之后,后续语句如何执行,以及相关job下次执行时间怎样进行更新

时间:2022-07-18 17:17:06

通过测试得到以下结论:

1、存储过程中出现报错之后,从此报错点开始,后面所有语句都放弃执行

2、存储过程报错之后,JOB的下次执行时间不会按照interval的设置来更新,但如果存储过程的报错通过exception进行了捕获,则JOB的下次执行时间正常按照interval的设置来更新

3、存储过程中设立子程序捕获报错,在捕获点之后的语句会正常执行

 

下为测试过程

 

--创建临时表,存放两个字段

create table tmp_lixiong_test_table(

test_id varchar2(4),

test_area varchar2(2));

 

--创建唯一索引

create unique index idx_tmp_lixiong_test_table on tmp_lixiong_test_table(test_id,test_area);

 

--创建存储过程

CREATE OR REPLACE PROCEDURE prc_lixiong_test_error2(pa_date IN DATE DEFAULT trunc(SYSDATE)) IS

  v_date       DATE;

  v_cnt        INT;

  v_start_time date;

BEGIN

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('00''00');

  commit;

 

END prc_lixiong_test_error2;

 

--创建存储过程

CREATE OR REPLACE PROCEDURE prc_lixiong_test_error(pa_date IN DATE DEFAULT trunc(SYSDATE)) IS

  v_date       DATE;

  v_cnt        INT;

  v_start_time date;

BEGIN

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('01''01');

  commit;

 

  FOR CCC IN (select '11' as test_area

                from dual

              union all

              select '12'

                from dual

              union all

              select '13'

                from dual) LOOP

  

    insert into tmp_lixiong_test_table

      (test_id, test_area)

    values

      ('02', ccc.test_area);

    commit;

  

  END LOOP;

  

  --内部调用prc_lixiong_test_error2

  prc_lixiong_test_error2;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('03''03');

  commit;

  

END prc_lixiong_test_error;

 

--第一次测试,测试存储过程在某一步报错之后是否还执行后面语句

 

--在tmp_lixiong_test_table为空表的情况下执行prc_lixiong_test_error

begin

  prc_lixiong_test_error;

end;

 

select * from tmp_lixiong_test_table;

 

--清空tmp_lixiong_test_table,并先插入一条数据,使循环的第二轮报错

truncate table tmp_lixiong_test_table;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('02''12');

  commit;

 

--再次执行prc_lixiong_test_error

begin

  prc_lixiong_test_error;

end;

 

select * from tmp_lixiong_test_table;

 

--第一次测试结论:存储过程中出现报错之后,从此报错点开始,后面所有语句都放弃执行

 

--第二次测试,测试语句报错之后,JOB的执行情况

 

--创建job

 

select * from dba_jobs d where lower(what) like '%prc_lixiong_test_error%';

 

--清空tmp_lixiong_test_table,并先插入一条数据,使循环的第二轮报错

truncate table tmp_lixiong_test_table;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('02''12');

  commit;

 

--第二次测试结论,存储过程报错之后,JOB的下次执行时间不会按照interval的设置来更新

 

--第三次测试,在存储过程中捕获报错的情况下,测试JOB的执行情况

--首先更新存储过程,如下:

CREATE OR REPLACE PROCEDURE prc_lixiong_test_error(pa_date IN DATE DEFAULT trunc(SYSDATE)) IS

  v_date       DATE;

  v_cnt        INT;

  v_start_time date;

BEGIN

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('01''01');

  commit;

 

  FOR CCC IN (select '11' as test_area

                from dual

              union all

              select '12'

                from dual

              union all

              select '13'

                from dual) LOOP

  

    insert into tmp_lixiong_test_table

      (test_id, test_area)

    values

      ('02', ccc.test_area);

    commit;

  

  END LOOP;

  

  --内部调用prc_lixiong_test_error2

  prc_lixiong_test_error2;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('03''03');

  commit;

EXCEPTION

  WHEN OTHERS THEN

    ROLLBACK;

END prc_lixiong_test_error;

 

select * from dba_jobs d where lower(what) like '%prc_lixiong_test_error%';

 

--清空tmp_lixiong_test_table,并先插入一条数据,使循环的第二轮报错

truncate table tmp_lixiong_test_table;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('02''12');

  commit;

 

--第三次测试结论,在存储过程中捕获报错的情况下,JOB的下次执行时间会按照interval的设置来更新

 

--第四次测试,在存储过程无效的情况下,测试JOB的执行情况

--创建job之后,使存储过程无效,如下:

CREATE OR REPLACE PROCEDURE prc_lixiong_test_error(pa_date IN DATE DEFAULT trunc(SYSDATE)) IS

  v_date       DATE;

  v_cnt        INT;

  v_start_time date;

BEGIN

 

  insert inot tmp_lixiong_test_table---这里into写错

    (test_id, test_area)

  values

    ('01''01');

  commit;

 

  FOR CCC IN (select '11' as test_area

                from dual

              union all

              select '12'

                from dual

              union all

              select '13'

                from dual) LOOP

  

    insert into tmp_lixiong_test_table

      (test_id, test_area)

    values

      ('02', ccc.test_area);

    commit;

  

  END LOOP;

  

  --内部调用prc_lixiong_test_error2

  prc_lixiong_test_error2;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('03''03');

  commit;

EXCEPTION

  WHEN OTHERS THEN

    ROLLBACK;

END prc_lixiong_test_error;

 

--第四次测试结论,在存储过程无效的情况下,JOB的下次执行时间不会按照interval的设置来更新

 

--第五次测试,存储过程中设立子程序捕获报错,测试后续语句的执行

--首先更新存储过程,如下:

 

CREATE OR REPLACE PROCEDURE prc_lixiong_test_error(pa_date IN DATE DEFAULT trunc(SYSDATE)) IS

  v_date       DATE;

  v_cnt        INT;

  v_start_time date;

BEGIN

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('01''01');

  commit;

 

begin

  FOR CCC IN (select '11' as test_area

                from dual

              union all

              select '12'

                from dual

              union all

              select '13'

                from dual) LOOP

  

    insert into tmp_lixiong_test_table

      (test_id, test_area)

    values

      ('02', ccc.test_area);

    commit;

  

  END LOOP;

 

EXCEPTION

  WHEN OTHERS THEN

    ROLLBACK;

    system_log('transport_data_lixiong');

end;

  

  --内部调用prc_lixiong_test_error2

  prc_lixiong_test_error2;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('03''03');

  commit;

  

END prc_lixiong_test_error;

 

--清空tmp_lixiong_test_table,并先插入一条数据,使循环的第二轮报错

truncate table tmp_lixiong_test_table;

 

  insert into tmp_lixiong_test_table

    (test_id, test_area)

  values

    ('02''12');

  commit;

 

select * from tmp_lixiong_test_table;

 

--执行prc_lixiong_test_error

begin

  prc_lixiong_test_error;

end;

 

--第五次测试结论,存储过程中设立子程序捕获报错,在捕获点之后的语句会正常执行

 

--删除相关表和存储过程

drop table tmp_lixiong_test_table;

drop procedure prc_lixiong_test_error;