Oracle PL/SQL Tutorial/Trigger/Utility trigger

Материал из SQL эксперт
Перейти к: навигация, поиск

A trigger prevents updates after business hours

   <source lang="sql">

SQL> SQL> SQL> create table employee(

 2           emp_no                 integer     primary key
 3          ,lastname               varchar2(20)    not null
 4          ,firstname              varchar2(15)    not null
 5          ,midinit                varchar2(1)
 6          ,street                 varchar2(30)
 7          ,city                   varchar2(20)
 8          ,state                  varchar2(2)
 9          ,zip                    varchar2(5)
10          ,zip_4                  varchar2(4)
11          ,area_code              varchar2(3)
12          ,phone                  varchar2(8)
13          ,salary                 number(5,2)
14          ,birthdate              date
15          ,hiredate               date
16          ,title                  varchar2(20)
17          ,dept_no                integer
18        ,mgr              integer
19        ,region           number
20        ,division         number
21        ,total_sales          number
22         );

Table created. SQL> SQL> SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip,zip_4, area_code, phone, birthdate, title)

 2  values (1,"Gardinia","Joy","R","688 Ave","New York","NY","12122","2333","212","200-3393","12-nov-1956","President");

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values (2,"Anderson","Lucy","J","33 Ave","New York","NY","43552","6633","212","234-4444",7.75,"21-mar-1951","1-feb-1994","Sales Manager",2,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate,title, dept_no, mgr, region, division, total_sales)

 2  values (3,"Somers","Ingrid","E","12 Ave","New York","NY","76822","8763","212","867-6893",7.75,"14-feb-1963","15-mar-1995","Sales Clerk",2,2,100,10,10000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip,zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values (4,"Washington","Georgia","J","13th Street","New York","NY","43122","4333","212","340-4365",11.50,"2-jul-1963","21-apr-1994","Designer",1,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values (5,"Doright","Dudley","J","56 Langer Street","Staten Island","NY","23332","4983","718","777-4365",21.65,"15-may-1958","2-aug-1994","Designer",1,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip,zip_4, area_code, phone, salary, birthdate, hiredate,title, dept_no, mgr, region, division, total_sales)

 2  values ( 6,"Doright","Dorothy","R","56 Langer Street","Staten Island","NY","23332","4983","718","777-4365",24.65,"10-dec-1968","2-aug-1994","Designer",1,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values ( 7,"Perry","Donna","R","1st Ave","New York","NY","44444","3444","212","111-6893",7.75,"14-feb-1967","15-mar-1995","Sales Clerk",2,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values ( 8,"Roger","John","E","67 H Ave","New York","NY","33822","1163","212","122-6893",10.00,"14-jun-1956","15-mar-1995","Accountant",3,1,100,10,40000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values ( 9,"Hall","Ted","R","1236 Lane","New York","NY","33823","1164","212","222-4393",13.00,"10-jun-1959","15-aug-1997","Sales Representative",3,1,100,10,50000);

1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dept_no, mgr, region, division, total_sales)

 2  values ( 10,"Barbee","Candice","L","400 Street","New York","NY","33811","2009","212","321-6873",12.00,"10-oct-1964","15-jan-1999","Sales Representative",3,1,100,10,35000);

1 row created. SQL> SQL> create or replace trigger tr_emp_maint_restrict

 2  before update or insert or delete
 3  on employee
 4  begin
 5    if to_char(sysdate, "hh24") >= "09" AND
 6       to_char(sysdate, "hh24") <= "17" then
 7       null;
 8    else
 9          raise_application_error (-20000, "Employee info may not be modified at this time!") ;
10    end if ;
11  end ;
12  /

Trigger created. SQL> SQL> --to test SQL> update employee set area_code = 212 where emp_no = 1; update employee set area_code = 212 where emp_no = 1

      *

ERROR at line 1: ORA-20000: Employee info may not be modified at this time! ORA-06512: at "sqle.TR_EMP_MAINT_RESTRICT", line 6 ORA-04088: error during execution of trigger "sqle.TR_EMP_MAINT_RESTRICT"

SQL> SQL> SQL> SQL> drop table employee; Table dropped. SQL> SQL></source>


Records a error in the error logging table.

   <source lang="sql">

SQL> SQL> SQL> CREATE SEQUENCE system_error_id NOCACHE; Sequence created. SQL> SQL> CREATE TABLE system_errors

 2     (system_error_id  NUMBER(10,0), package_name  VARCHAR2(50),
 3      procedure_name  VARCHAR2(50), execution_location  varchar2(20),
 4      oracle_error_text  VARCHAR2(200),
 5      additional_information  VARCHAR2(2000),
 6      call_stack   VARCHAR2(2000), error_stack  VARCHAR2(2000),
 7      insert_time  DATE, insert_user  VARCHAR2(30));

Table created. SQL> SQL> COMMENT ON TABLE system_errors IS

 2     "Errors generated by stored packages.";

Comment created. SQL> COMMENT ON COLUMN system_errors.system_error_id IS

 2     "The system-wide ID to identify a system error. Useful for
 3      determining the order in which errors were encountered and
 4      logged.";

Comment created. SQL> COMMENT ON COLUMN system_errors.package_name IS "The package name."; Comment created. SQL> COMMENT ON COLUMN system_errors.procedure_name IS "The procedure/function name."; Comment created. SQL> COMMENT ON COLUMN system_errors.execution_location IS "A reference to a location in the executing code."; Comment created. SQL> COMMENT ON COLUMN system_errors.oracle_error_text IS "The text of the Oracle error message."; Comment created. SQL> COMMENT ON COLUMN system_errors.additional_information IS "Any pertinent information the developer may be trapping by the error handler."; Comment created. SQL> COMMENT ON COLUMN system_errors.call_stack IS "The call stack at the time of the error."; Comment created. SQL> COMMENT ON COLUMN system_errors.error_stack IS "The error stack at the time of the error."; Comment created. SQL> COMMENT ON COLUMN system_errors.insert_time IS "The date and time of record insertion."; Comment created. SQL> COMMENT ON COLUMN system_errors.insert_user IS "The user inserting the record."; Comment created. SQL> SQL> CREATE OR REPLACE PROCEDURE log_error

 2     (p_package_txt   VARCHAR2 DEFAULT "UNKNOWN",
 3     p_procedure_txt VARCHAR2 DEFAULT "UNKNOWN",
 4     p_location_txt  VARCHAR2 DEFAULT "UNKNOWN",
 5     p_error_txt     VARCHAR2 DEFAULT "UNKNOWN",
 6     p_text_txt      VARCHAR2 DEFAULT "NONE",
 7     p_commit_bln    BOOLEAN  DEFAULT TRUE,
 8     p_user_txt      VARCHAR2 DEFAULT USER,
 9     p_time_date     DATE     DEFAULT SYSDATE) IS
10     lv_call_stack_txt VARCHAR2(2000);
11     lv_error_stack_txt VARCHAR2(2000);
12     pu_failure_excep EXCEPTION;
13     PRAGMA EXCEPTION_INIT (pu_failure_excep, -20000);
14  BEGIN
15     lv_call_stack_txt := SUBSTR(DBMS_UTILITY.FORMAT_CALL_STACK, 1, 2000);
16     lv_error_stack_txt := SUBSTR(DBMS_UTILITY.FORMAT_ERROR_STACK, 1, 2000);
17     INSERT INTO system_errors (system_error_id, package_name, procedure_name,
18         execution_location, oracle_error_text, additional_information,
19         call_stack, error_stack, insert_time, insert_user)
20     VALUES (system_error_id.NEXTVAL, SUBSTR(p_package_txt, 1, 50),
21         SUBSTR(p_procedure_txt, 1, 50),
22         SUBSTR(p_location_txt, 1, 20), SUBSTR(p_error_txt, 1, 200),
23         SUBSTR(p_text_txt, 1, 2000), lv_call_stack_txt,
24         lv_error_stack_txt, p_time_date, p_user_txt);
25     IF p_commit_bln THEN
26        COMMIT;
27      END IF;
28  EXCEPTION
29     WHEN OTHERS THEN
30        RAISE pu_failure_excep;
31  END log_error;
32  /

Procedure created. SQL> SQL> drop sequence system_error_id; Sequence dropped. SQL> SQL> SQL> drop table system_errors; Table dropped.</source>


Use trigger to keep data consistency

   <source lang="sql">

SQL> SQL> SQL> create table ord

 2          (
 3           order_no               integer         primary key
 4          ,empl_no                integer
 5          ,order_date             date not null
 6          ,total_order_price      number(7,2)
 7          ,deliver_date           date
 8          ,deliver_time           varchar2(7)
 9          ,payment_method         varchar2(2)
10          ,emp_no                 number(3,0)
11          ,deliver_name           varchar2(35)
12          ,gift_message           varchar2(100)
13           );

Table created. SQL> SQL> SQL> SQL> insert into ord(order_no,empl_no,order_date,total_order_price,deliver_date,deliver_time,payment_method,emp_no,deliver_name,gift_message)

 2  values(1,1,add_months(sysdate, -1), 235.00, "14-Feb-1999", "12 noon", "CA",1, null, "Gift for wife");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time ,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(2,1,add_months(sysdate, -2), 50.98, "14-feb-1999", "1 pm", "CA",7, "Rose", "Happy Valentines Day to Mother");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(3, 2,add_months(sysdate, -3), 35.99, "14-feb-1999", "1 pm", "VS",2, "Ruby", "Happy Valentines Day to Mother");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(4, 2,add_months(sysdate, -4), 19.95, "14-feb-1999", "5 pm", "CA",2, "Coy", "Happy Valentines Day to You");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(7, 9,add_months(sysdate, -7), 35.95, "21-jun-1999", "12 noon", "VS", 2, "Fill", "Happy Birthday from Joe");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values (8, 12, add_months(sysdate, -8), 35.95, "1-jan-2000", "12 noon", "DI",3, "Laura", "Happy New Year""s from Lawrence");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values (9, 12, add_months(sysdate, -9), 75.95, "2-jan-2000", "12 noon", "CA",7, "Sara", "Happy Birthday from Lawrence" );

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(10, 4, add_months(sysdate, -10), 19.95, sysdate, "2:30 pm", "VG",2, "OK", "Happy Valentines Day to You");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message )

 2  values(11, 2, add_months(sysdate, -11), 30.00, sysdate+2, "1:30 pm", "VG",2, "Hi", "Happy Birthday Day to You");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message)

 2  values(12, 7, add_months(sysdate, -12), 21.95, sysdate-2, "3:30 pm", "CA",2, "Jack", "Happy Birthday Day to You");

1 row created. SQL> SQL> insert into ord(order_no ,empl_no ,order_date ,total_order_price ,deliver_date ,deliver_time,payment_method ,emp_no,deliver_name ,gift_message)

 2  values(13, 7, add_months(sysdate, -1), 21.95, sysdate, "3:30 pm", "CA",2, "Jay", "Thanks for giving 100%!");

1 row created. SQL> SQL> SQL> SQL> SQL> create table ord_item

 2          (
 3           order_no               integer
 4          ,product_id             integer
 5          ,quantity               number(4,0)
 6          ,item_price                 number(7,2)
 7        ,total_order_item_price   number(9,2)
 8          ,primary key (order_no ,product_id)
 9          );

Table created. SQL> SQL> SQL> SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(1, 2, 10, 23.00 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(2, 1, 1, 23.00 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(2, 5, 1, 10.50 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(2, 8, 1, 17.48 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(3, 8, 1, 35.99 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(4, 7, 1, 19.95 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(5, 5, 1, 10.95 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(6, 8, 1, 22.95 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(7, 1, 6, 15.00 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(7, 5, 1, 10.50 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(7, 8, 1, 10.45 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(8, 8, 1, 35.95 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(9, 8, 1, 65.45 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(9, 5, 1, 10.50 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(10, 3, 1, 19.95 ); 1 row created. SQL> insert into ord_item (order_no, product_id, quantity, item_price) values(11, 8, 1, 30.00); 1 row created. SQL> SQL> SQL> SQL> SQL> SQL> create or replace trigger tr_total_order_price

 2  after
 3  update of item_price or insert or delete
 4  on ord_item
 5  for each row
 6  declare
 7      v_change_in_price  number;
 8      v_order_no number;
 9  begin
10  if inserting then
11      v_change_in_price := :new.item_price * :new.quantity ;
12      v_order_no := :new.order_no;
13      dbms_output.put_line("inserting");
14  elsif updating then
15      v_change_in_price := (:new.item_price * :new.quantity) - (:old.item_price * :old.quantity) ;
16      v_order_no := :old.order_no;
17      dbms_output.put_line("updating");
18  else
19      v_change_in_price := (:old.item_price * :old.quantity)  * -1;
20      v_order_no := :old.order_no;
21      dbms_output.put_line("deleting");
22  end if;
23
24  update ord
25  set total_order_price = total_order_price + v_change_in_price
26  where order_no = v_order_no;
27  end;
28  /

Trigger created. SQL> SQL> update ord_item set item_price = 25 where order_no = 7 and product_id = 5 ; 1 row updated. SQL> SQL> SQL> drop table ord; Table dropped. SQL> SQL> drop table ord_item; Table dropped. SQL></source>