ORACLE 触发器 基础

Posted AF陈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE 触发器 基础相关的知识,希望对你有一定的参考价值。

--触发器
--语法

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/

 




以上是关于ORACLE 触发器 基础的主要内容,如果未能解决你的问题,请参考以下文章

带有 Oracle 触发键列的 ODBC

ORACLE 触发器 基础

sql Oracle代码片段

oracle(sql)基础篇系列——PLSQL游标存储过程触发器

如何在 Toad for Oracle 中使用自定义代码片段?

如何设置 vscode 的代码片段,以便在自动完成后自动触发 vscode 的智能感知?