1. /*the experiment environment*/ 
  2. create table parent ( p1 varchar2(100),p2 varchar2(100) ); 
  3. create table son(s1 number,s2 varchar2(100)); 
  4. create table log_table(user_id varchar2(100),error_date date,error_action varchar2(20)); 
  5.  
  6. hr>insert  into parent values('A','B'); 
  7.   >commit
  8. sys>alter user sh account unlock identified by sh; 
  9.  
  10. /*create procedure to record error action*/ 
  11. create or replace 
  12. procedure proc_ins_log( 
  13. p_act varchar2 
  14. is 
  15.  begin 
  16.    insert  into log_table values(user,sysdate,p_act); 
  17.    end  proc_ins_log;  
  18. /*create procedure to insert values to son table*/ 
  19. create or replace procedure proc_ins_son( 
  20. p_s1 son.s1%type, 
  21. p_s2 son.s2%type, 
  22. p_count  out  number 
  23. is  
  24.    v_count number :=0; 
  25.    e_foreign_key exception; 
  26.    e_primary_key exception; 
  27.  begin 
  28.     for rec in (select  p1 from parent ) loop 
  29.      if rec.p1=p_s2  
  30.      then 
  31.          v_count :=v_count+1; 
  32.          end if; 
  33.       end loop; 
  34.       ---primary exception 
  35.        for rec in (select s1 from son) loop 
  36.          if p_s1=rec.s1 then 
  37.             raise e_primary_key; 
  38.         end if; 
  39.         end loop; 
  40.     ----foreignkey exception 
  41.     if v_count=0 then 
  42.       raise e_foreign_key; 
  43.       end if; 
  44.       ---normal 
  45.       insert into son values(p_s1,p_s2); 
  46.       commit
  47.       select count(*) into p_count from son; 
  48.       exception 
  49.         when e_foreign_key then 
  50.          rollback
  51.          dbms_output.put_line('foreign_error'); 
  52.          proc_ins_log('foreign_key_error'); 
  53.         when e_primary_key then 
  54.         rollback
  55.           dbms_output.put_line('primary_key'); 
  56.           proc_ins_log('primary_key_error'); 
  57.           end
  58.            
  59.           select * from user_errors; 
  60. -----test 
  61. hr>grant execute  on proc_ins_son  to sh; 
  62.   >grant select  on log_table  to sh; 
  63.   >grant select  on prant  to sh; 
  64.   >grant select  on son  to sh; 
  65.  
  66.  
  67. sh> select * from parent; 
  68.  
  69. P1  P2 
  70. A   B 
  71.  
  72.  
  73. sh> select * from hr.son; 
  74.  
  75. S1  S2 
  76. 1   A 
  77.  
  78. hr>select * from parent; 
  79.  
  80. P1 P2 
  81. A  B 
  82.  
  83.  
  84.  
  85. sh> set serverout on
  86. sh> ed 
  87. Wrote file afiedt.buf 
  88.  
  89.   1  declare 
  90.   2   v_count number; 
  91.   3   begin 
  92.   4 hr.proc_ins_son(1,'A',v_count); 
  93.   5 dbms_output.put_line(v_count); 
  94.   6* end
  95. sh> / 
  96. primary_key 
  97.  
  98. PL/SQL procedure successfully completed. 
  99.  
  100.  
  101.  
  102. sh> ed 
  103. Wrote file afiedt.buf 
  104.  
  105.   1  declare 
  106.   2   v_count number; 
  107.   3   begin 
  108.   4 hr.proc_ins_son(2,'B',v_count); 
  109.   5 dbms_output.put_line(v_count); 
  110.   6* end
  111. SQL> / 
  112. foreign_error 
  113.  
  114. PL/SQL procedure successfully completed. 
  115.  
  116.  
  117. sh> ed 
  118. Wrote file afiedt.buf 
  119.  
  120.   1  declare 
  121.   2   v_count number; 
  122.   3   begin 
  123.   4 hr.proc_ins_son(1,'B',v_count); 
  124.   5 dbms_output.put_line(v_count); 
  125.   6* end
  126. sh> / 
  127. primary_key  /*when two errors are raise in the same time ,firstly to raise the first exception you catch*/  
  128.  
  129. PL/SQL procedure successfully completed.