--触发器
--语法
CREATE OR REPLACE TRIGGER TRIGGER_NAME AFTER|BEFORE|INSTEAD OF [INSERT][OR UPDATE [OF COLUMN_LIST]] [OR [DELETE]] ON TABLE_OR_VIEW_NAME [REFERENCING{OLD[AS]OLD/NEW[AS]NEW} ] [FOR EACH ROW] [WHEN(condition)] pl/sql_block; --sqlserver oracel deleted :old inserted :new
--触发器中不能使用 ROLLBACK ,COMMIT,SAVEPOINT
--如果在触发器中PLSQL使用了:NEW :OLD时,就必须是行级触发器,必须要有 FOR EACH ROW
--创建实验环境 CREATE TABLE SC(CODE NUMBER ,SNAME VARCHAR2(10),SCORE NUMBER); INSERT INTO SC VALUES (1,'AA',87); INSERT INTO SC VALUES (2,'BB',67); INSERT INTO SC VALUES (3,'CC',57); INSERT INTO SC VALUES (4,'DD',88); COMMIT; SELECT * FROM SC; SET SERVEROUT ON CREATE OR REPLACE TRIGGER TRIG1 BEFORE INSERT OR UPDATE ON SC FOR EACH ROW BEGIN DBMS_OUTPUT.put_line('TRIG1 IS VALID'); END; / INSERT INTO SC VALUES (5,'EE',90); UPDATE SC SET SCORE=SCORE+1; ROLLBACK; --SCORE 必须在0-100中 CREATE OR REPLACE TRIGGER TRIG2 BEFORE INSERT ON SC FOR EACH ROW --使用了:NEW,:OLD时必须要有这句话 BEGIN IF :NEW.SCORE<0 OR :NEW.SCORE>100 THEN RAISE_APPLICATION_ERROR(-20001,'ERROR'); END IF; END; / INSERT INTO SC VALUES (6,'EE',-1); INSERT INTO SC VALUES (6,'EE',101); INSERT INTO SC VALUES (6,'EE',10); ROLLBACK;
--当插入的CODE是负数时,将其转为正数再插入 必须在0-100中 CREATE OR REPLACE TRIGGER TRIG3 BEFORE INSERT ON SC FOR EACH ROW BEGIN IF :NEW.CODE < 0 THEN :NEW.CODE := -:NEW.CODE; END IF; END; / INSERT INTO SC VALUES (-7,'EE',90);
--当用户对表进行操作时记录操作 CREATE OR REPLACE TRIGGER TRIG5 BEFORE INSERT OR UPDATE OR DELETE ON SC FOR EACH ROW BEGIN IF INSERTING --关键词 THEN DBMS_OUTPUT.PUT_LINE('INSERT:'||:NEW.CODE||','||:NEW.NAME||','||:NEW.SCORE); END IF; IF DELETING --关键词 THEN DBMS_OUTPUT.PUT_LINE('DELETE:'||:OLD.CODE||','||:OLD.NAME||','||:OLD.SCORE); END IF; IF UPDATING --关键词 THEN DBMS_OUTPUT.PUT_LINE('UPDATE_B:'||:OLD.CODE||','||:OLD.NAME||','||:OLD.SCORE); DBMS_OUTPUT.PUT_LINE('UPDATE_A:'||:NEW.CODE||','||:NEW.NAME||','||:NEW.SCORE); END IF; END; / INSERT INTO SC VALUES (10,'EE',90); UPDATE SC SET SCORE=100 WHERE CODE=10; DELETE SC WHERE CODE=10;
--用触发器修改视图(非键保留表) --创建实验环境 CREATE TABLE STUDENT (SNO INT ,SNAME VARCHAR2(10),SAGE INT); INSERT INTO STUDENT VALUES (1,'AA',22); INSERT INTO STUDENT VALUES (2,'BB',23); INSERT INTO STUDENT VALUES (3,'CC',24); INSERT INTO STUDENT VALUES (4,'DD',25); INSERT INTO STUDENT VALUES (5,'EE',26); CREATE TABLE ADDRESS (SNO INT ,ZZ VARCHAR2(10)); INSERT INTO ADDRESS VALUES (1,'ZZ'); INSERT INTO ADDRESS VALUES (2,'LY'); INSERT INTO ADDRESS VALUES (3,'KF'); INSERT INTO ADDRESS VALUES (4,'XX'); INSERT INTO ADDRESS VALUES (5,'XC'); COMMIT; GRANT CREATE VIEW TO SCOTT ; --DBA CREATE OR REPLACE VIEW V1 AS SELECT A.SNO,A.SNAME ,A.SAGE,B.ZZ FROM STUDENT A LEFT JOIN ADDRESS B ON A.SNO=B.SNO; --实现更新操作 UPDATE V1 SET ZZ='AY' WHERE SNAME = 'BB'; -- ORA-01779: cannot modify a column which maps to a non key-preserved table CREATE OR REPLACE TRIGGER TRIG4 INSTEAD OF UPDATE ON V1 FOR EACH ROW DECLARE A NUMBER :=0; --用在存储SNO BEGIN SELECT SNO INTO A FROM STUDENT WHERE SNAME = :OLD.SNAME; --赋值 DELETE ADDRESS WHERE SNO=A; --删除原数据 INSERT INTO ADDRESS VALUES (A,:NEW.ZZ); --插入新数据 END; / UPDATE V1 SET ZZ='AY' WHERE SNAME = 'BB';
--模式触发器 --例 CREATE TABLE DROPPDE_OBJ(OBJ_NAME VARCHAR2(30),OBJ_TYPE VARCHAR2(20),DROP_DATE DATE); CREATE OR REPLACE TRIGGER LOG_DROP_OBJ AFTER DROP --类型 ON SCHEMA --模式 BEGIN INSERT INTO DROPPED_OBJ VALUES (ora_dict_obj_name,ora_dict_obj_type,SYSDATE); END; / CREATE TABLE TT (ID INT); DROP TABLE TT ; ora_client_ip_address --返回客户端的IP ora_database_name --返回当前数据库名 ora_login_user --返回登录用户名 ora_dict_obj_name --返回DDL操作对应的数据库对象名 ora_dict_obj_type --返回DDL操作对应的数据库对象类型
--数据库启动、关闭 触发器 --SYS使用 --数据库启动触发器 CREATE TABLE EVENT_TABLE (EVENT VARCHAR2(30),TIME DATE); CREATE OR REPLACE TRIGGER TR_STARTUP AFTER STARTUP --AFTER ON DATABASE BEGIN INSERT INTO EVENT_TABLE VALUES (ora_sysevent,SYSDATE); END; / --数据库关闭触发器 CREATE OR REPLACE TRIGGER TR_STARTUP BEFORE SHUTDOWN --BEFORE ON DATABASE BEGIN INSERT INTO EVENT_TABLE VALUES (ora_sysevent,SYSDATE); END; /
--用户登录和退出触发器 CREATE TABLE LOGIN_TABLE (USERNAME VARCHAR2(10),LOGON_TIME DATE,LOGOFF_TIME DATE,ADDRESS VARCHAR2(30)); --登陆 CREATE OR REPLACE TRIGGER TRIG_LOGON AFTER LOGON ON DATABASE BEGIN INSERT INTO LOGIN_TABLE(USERNAME,LOGON_TIME,ADDRESS) VALUES (ora_login_user,SYSDATE,ora_client_ip_address); END; / --退出 CREATE OR REPLACE TRIGGER TRIG_LOGOFF BEFORE LOGOFF ON DATABASE BEGIN INSERT INTO LOGIN_TABLE(USERNAME,LOGOFF_TIME,ADDRESS) VALUES (ora_login_user,SYSDATE,ora_client_ip_address); END; /
--启用、禁用与删除 ALTER TRIGGER TRIGGER_NAME DISABLE; ALTER TRIGGER TRIGGER_NAME ENABLE; DROP TRIGGER TRIGGER_NAME ; --查看触发器相关信息 SELECT * FROM USER_TRIGGERS;
--更多内容可以查看:http://blog.csdn.net/indexman/article/details/8023740/