ORACLE 觸發器語法及例項 二

達芬奇的夢發表於2017-05-16

begin

if inserting then

:new.job:=upper(:new.job);

else

:new.job:=upper(:new.job);

end if;

end;

instead of 觸發器.

(此觸發器是在檢視上而不是在表上定義的觸發器,它是用來替換所使用實際語句的觸發器.)

語法如下:

create or replace trigger trig_test

instead of insert or update on 表名

referencing new as n

for each row

declare

..........

begin

........

end;

、模式觸發器.

可以在模式級的操作上建立觸發器.

例項如下:

create or replace trigger log_drop_obj

after drop on schema

begin

insert into .....

end;

、資料庫級觸發器.

可以建立在資料庫事件上的觸發器,包括關閉,啟動,伺服器錯誤,登入等.這些事件都是例項範圍的,不與特定的表或檢視關聯.

例項:

create or replace trigger trig_name

after startup on database

begin

...........

end;

OK,大概就這些了.

、例子:

需要對在表上進行DML操作的使用者進行安全檢查,看是否具有合適的特權。

Create table foo(a number);

Create trigger biud_foo

       Before insert or update or delete

       On foo

Begin

    If user not in (‘DONNY’) then

       Raise_application_error(-20001, ‘You don’t have access to modify this table.’);

    End if;

End;

/

即使SYSSYSTEM使用者也不能修改foo

[試驗]

對修改表的時間、人物進行日誌記錄。

1、 建立試驗表

create table employees_copy as select *from hr.employees

2、 建立日誌表

create table employees_log(

        who varchar2(30),

        when date);

3、 在employees_copy表上建立語句觸發器,在觸發器中填充employees_log 表。

Create or replace trigger biud_employee_copy

       Before insert or update or delete

       On employees_copy

       Begin

           Insert into employees_log(Who,when)

           Values( user, sysdate);

       End;

       /

4、 測試

update employees_copy set salary= salary*1.1;

select *from employess_log;

5、 確定是哪個語句起作用?

即是INSERT/UPDATE/DELETE中的哪一個觸發了觸發器?

可以在觸發器中使用INSERTING / UPDATING / DELETING 條件謂詞,作判斷:

begin

        if inserting then

               -----

        elsif updating then

               -----

        elsif deleting then

               ------

        end if;

end;

if updating(‘COL1’) or updating(‘COL2’) then

        ------

end if;

[試驗]

1、 修改日誌表

alter table employees_log

add (action varchar2(20));

2、 修改觸發器,以便記錄語句型別。

Create or replace trigger biud_employee_copy

Before insert or update or delete

On employees_copy

Declare

L_action employees_log.action%type;

Begin

if inserting then

l_action:=’Insert’;

elsif updating then

l_action:=’Update’;

elsif deleting then

l_action:=’Delete’;

else

raise_application_error(-20001,’You should never ever get this error.’);

Insert into employees_log(Who,action,when)

Values( user, l_action,sysdate);

End;

/

3、 測試

insert into employees_copy( employee_id, last_name, email, hire_date, job_id)

       values(12345,’Chen’,’Donny@hotmail’,sysdate,12);

select *from employees_log

--建立觸發器,當使用者對test表執行DML語句時,將相關資訊記錄到日誌表

--建立測試表

CREATE TABLE test

(

t_id   NUMBER(4),

t_name VARCHAR2(20),

t_age NUMBER(2),

t_sex CHAR

);

--建立記錄測試表

CREATE TABLE test_log

(

l_user   VARCHAR2(15),

l_type   VARCHAR2(15),

l_date   VARCHAR2(30)

);

--建立觸發器

CREATE OR REPLACE TRIGGER test_trigger

AFTER DELETE OR INSERT OR UPDATE ON test

DECLARE

v_type test_log.l_type%TYPE;

BEGIN

IF INSERTING THEN --INSERT觸發

   v_type := 'INSERT';

   DBMS_OUTPUT.PUT_LINE('記錄已經成功插入,並已記錄到日誌');

ELSIF UPDATING THEN --UPDATE觸發

   v_type := 'UPDATE';

   DBMS_OUTPUT.PUT_LINE('記錄已經成功更新,並已記錄到日誌');

ELSIF DELETING THEN

   v_type := 'DELETE';

   DBMS_OUTPUT.PUT_LINE('記錄已經成功刪除,並已記錄到日誌');

END IF;

INSERT INTO test_log VALUES(user,v_type, TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss'));

END;

/

--下面我們來分別執行DML語句

INSERT INTO test VALUES(101,'zhao',22,'M');

UPDATE test SET t_age = 30 WHERE t_id = 101;

DELETE test WHERE t_id = 101;

--然後檢視效果

SELECT * FROM test;

SELECT * FROM test_log;

--建立觸發器,它將對映emp表中每個部門的總人數和總工資

--建立對映表

CREATE TABLE dept_sal

    AS

    SELECT deptno,COUNT(empno) AS total_emp,SUM(sal) AS total_sal

FROM emp

GROUP BY deptno;

DESC dept_sal;

--建立觸發器

CREATE OR REPLACE TRIGGER emp_info

AFTER INSERT OR UPDATE OR DELETE ON emp

DECLARE

CURSOR cur_emp IS

SELECT deptno,COUNT(empno) AS total_emp,SUM(sal) AS total_sal

FROM emp

GROUP BY deptno;

BEGIN

 DELETE dept_sal;  --觸發時首先刪除對映表資訊

 FOR v_emp IN cur_emp LOOP

   --DBMS_OUTPUT.PUT_LINE(v_emp.deptno || v_emp.total_emp || v_emp.total_sal);

   --插入資料

   INSERT INTO dept_sal

    VALUES(v_emp.deptno,v_emp.total_emp,v_emp.total_sal);

 END LOOP;

END;

/

--emp表進行DML操作

INSERT INTO emp(empno,deptno,sal) VALUES('123','10',10000);

SELECT * FROM dept_sal;

DELETE EMP WHERE empno=123;</o:p

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31444259/viewspace-2139138/,如需轉載,請註明出處,否則將追究法律責任。

相關文章