Oracle触发器用法--基础教学
1、触发器简介
触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行。因此触发器不需要人为的去调用,也不能调用。然后,触发器的触发条件其实在你定义的时候就已经设定好了。这里面需要说明一下,触发器可以分为语句级触发器和行级触发器。详细的介绍可以参考网上的资料,简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发。而行级触发器则是在定义的了触发的表中的行数据改变时就会被触发一次。
具体举例:
1、 在一个表中定义的语句级的触发器,当这个表被删除时,程序就会自动执行触发器里面定义的操作过程。这个就是删除表的操作就是触发器执行的条件了。
2、 在一个表中定义了行级的触发器,那当这个表中一行数据发生变化的时候,比如删除了一行记录,那触发器也会被自动执行了。
2、触发器语法
- 触发器语法:
- create [or replace] tigger 触发器名 触发时间 触发事件 on 表名 [for each row] begin pl/sql语句 end
其中:
触发器名:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:
before:表示在数据库动作之前触发器执行;
after:表示在数据库动作之后触发器执行。
触发事件:指明哪些数据库动作会触发此触发器:
insert:数据库插入会触发此触发器;
update:数据库修改会触发此触发器;
delete:数据库删除会触发此触发器。
表 名:数据库触发器所在的表。
for each row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次。
- 触发器能实现如下功能:
1、 允许/限制对表的修改
2、 自动生成派生列,比如自增字段
3、 强制数据一致性
4、 提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑
举例:
1)、下面的触发器在更新表tb_emp之前触发,目的是不允许在周末修改表:
- create or replace trigger auth_secure before insert or update or DELETE
- on tb_emp
- begin
- IF(to_char(sysdate,'DY')='星期日') THEN
- RAISE_APPLICATION_ERROR(-20600,'不能在周末修改表tb_emp');
- END IF;
- END;
2)、使用触发器实现序号自增
创建一个测试表:
- create table tab_user(
- id number(11) primary key,
- username varchar(50),
- password varchar(50)
- );
创建一个序列:
- create sequence my_seq increment by 1 start with 1 nomaxvalue nocycle cache 20;
创建一个触发器:
- CREATE OR REPLACE TRIGGER MY_TGR
- BEFORE INSERT ON TAB_USER
- FOR EACH ROW--对表的每一行触发器执行一次
- DECLARE
- NEXT_ID NUMBER;
- BEGIN
- SELECT MY_SEQ.NEXTVAL INTO NEXT_ID FROM DUAL;
- :NEW.ID := NEXT_ID; --:NEW表示新插入的那条记录
- END;
向表插入数据:
- insert into tab_user(username,password) values('admin','admin');
- insert into tab_user(username,password) values('fgz','fgz');
- insert into tab_user(username,password) values('test','test');
- COMMIT;
查询表结果:
- SELECT * FROM TAB_USER;
3)、当用户对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 DELETING THEN
- --DELETE触发
- 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')); --USER表示当前用户名
- 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;
运行结果如下:
4)、创建触发器,它将映射emp表中每个部门的总人数和总工资
- --创建映射表
- CREATE TABLE dept_sal AS
- SELECT deptno, COUNT(empno) total_emp, SUM(sal) total_sal
- FROM scott.emp
- GROUP BY deptno;
- --创建触发器
- CREATE OR REPLACE TRIGGER EMP_INFO
- AFTER INSERT OR UPDATE OR DELETE ON scott.EMP
- DECLARE
- CURSOR CUR_EMP IS
- SELECT DEPTNO, COUNT(EMPNO) AS TOTAL_EMP, SUM(SAL) AS TOTAL_SAL FROM scott.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('','',10000);
- SELECT * FROM dept_sal;
- DELETE EMP WHERE empno=123;
- SELECT * FROM dept_sal;
显示结果如下:
5)、创建触发器,用来记录表的删除数据
- --创建表
- CREATE TABLE employee(
- id VARCHAR2(4) NOT NULL,
- name VARCHAR2(15) NOT NULL,
- age NUMBER(2) NOT NULL,
- sex CHAR NOT NULL
- );
- --插入数据
- INSERT INTO employee VALUES('e101','zhao',23,'M');
- INSERT INTO employee VALUES('e102','jian',21,'F');
- --创建记录表(包含数据记录)
- CREATE TABLE old_employee AS SELECT * FROM employee;
- --创建触发器
- CREATE OR REPLACE TRIGGER TIG_OLD_EMP
- AFTER DELETE ON EMPLOYEE
- FOR EACH ROW --语句级触发,即每一行触发一次
- BEGIN
- INSERT INTO OLD_EMPLOYEE VALUES (:OLD.ID, :OLD.NAME, :OLD.AGE, :OLD.SEX); --:old代表旧值
- END;
- /
- --下面进行测试
- DELETE employee;
- SELECT * FROM old_employee;
6)、创建触发器,利用视图插入数据
- --创建表
- CREATE TABLE tab1 (tid NUMBER(4) PRIMARY KEY,tname VARCHAR2(20),tage NUMBER(2));
- CREATE TABLE tab2 (tid NUMBER(4),ttel VARCHAR2(15),tadr VARCHAR2(30));
- --插入数据
- INSERT INTO tab1 VALUES(101,'zhao',22);
- INSERT INTO tab1 VALUES(102,'yang',20);
- INSERT INTO tab2 VALUES(101,'','AnHuiSuZhou');
- INSERT INTO tab2 VALUES(102,'','AnHuiSuZhou');
- --创建视图连接两张表
- CREATE OR REPLACE VIEW tab_view AS SELECT tab1.tid,tname,ttel,tadr FROM tab1,tab2 WHERE tab1.tid = tab2.tid;
- --创建触发器
- CREATE OR REPLACE TRIGGER TAB_TRIGGER
- INSTEAD OF INSERT ON TAB_VIEW
- BEGIN
- INSERT INTO TAB1 (TID, TNAME) VALUES (:NEW.TID, :NEW.TNAME);
- INSERT INTO TAB2 (TTEL, TADR) VALUES (:NEW.TTEL, :NEW.TADR);
- END;
- /
- --现在就可以利用视图插入数据
- INSERT INTO tab_view VALUES(106,'ljq','','beijing');
- --查询
- SELECT * FROM tab_view;
- SELECT * FROM tab1;
- SELECT * FROM tab2;
7)、创建触发器,比较emp表中更新的工资
- --创建触发器
- set serveroutput on;
- CREATE OR REPLACE TRIGGER SAL_EMP
- BEFORE UPDATE ON EMP
- FOR EACH ROW
- BEGIN
- IF :OLD.SAL > :NEW.SAL THEN
- DBMS_OUTPUT.PUT_LINE('工资减少');
- ELSIF :OLD.SAL < :NEW.SAL THEN
- DBMS_OUTPUT.PUT_LINE('工资增加');
- ELSE
- DBMS_OUTPUT.PUT_LINE('工资未作任何变动');
- END IF;
- DBMS_OUTPUT.PUT_LINE('更新前工资 :' || :OLD.SAL);
- DBMS_OUTPUT.PUT_LINE('更新后工资 :' || :NEW.SAL);
- END;
- /
- --执行UPDATE查看效果
- UPDATE emp SET sal = 3000 WHERE empno = '';
运行结果如下:
8)、创建触发器,将操作CREATE、DROP存储在log_info表
- --创建表
- CREATE TABLE log_info(
- manager_user VARCHAR2(15),
- manager_date VARCHAR2(15),
- manager_type VARCHAR2(15),
- obj_name VARCHAR2(15),
- obj_type VARCHAR2(15)
- );
- --创建触发器
- set serveroutput on;
- CREATE OR REPLACE TRIGGER TRIG_LOG_INFO
- AFTER CREATE OR DROP ON SCHEMA
- BEGIN
- INSERT INTO LOG_INFO
- VALUES
- (USER,
- SYSDATE,
- SYS.DICTIONARY_OBJ_NAME,
- SYS.DICTIONARY_OBJ_OWNER,
- SYS.DICTIONARY_OBJ_TYPE);
- END;
- /
- --测试语句
- CREATE TABLE a(id NUMBER);
- CREATE TYPE aa AS OBJECT(id NUMBER);
- DROP TABLE a;
- DROP TYPE aa;
- --查看效果
- SELECT * FROM log_info;
- --相关数据字典-----------------------------------------------------
- SELECT * FROM USER_TRIGGERS;
- --必须以DBA身份登陆才能使用此数据字典
- SELECT * FROM ALL_TRIGGERS;SELECT * FROM DBA_TRIGGERS;
- --启用和禁用
- ALTER TRIGGER trigger_name DISABLE;
- ALTER TRIGGER trigger_name ENABLE;
希望对大家有所帮助,感谢观看!!!
Oracle触发器用法--基础教学的更多相关文章
- Oracle触发器用法实例详解
转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...
- [转载]Oracle触发器用法实例详解
本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. 因此触发器不需要人为的去调用,也 ...
- Oracle触发器Trigger基础1
/* Trigger是作用在表上,或是数据库上,或是用户上.当用户在表上(其他)做某些操作时,trigger将会自己执行. 可以在表上:insert,update,delete Trigger只对表的 ...
- oracle入坑日记<六>自增列创建和清除(含序列和触发器的基础用法)
0 前言 用过 SQLserver 和 MySQL 的自增列(auto_increment),然而 Oracle 在建表设置列时却没有自增列. 查阅资料后发现 Oracle 的自增列需要手动编写. ...
- 【database】oracle触发器基础
一.oracle触发器基本语法 CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE | AFTER } {INSERT | DELETE | UPDATE ...
- oracle触发器应用
首先给大家推荐两篇我看后的博文,我已经内容转载过来: 1.对触发器的讲解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建 ...
- SQL server与Oracle触发器的创建与使用
SQL Server 1创建触发器 GO BEGIN IF (object_id('WMY', 'tr') is not null) DROP trigger WMY END; GO CREATE T ...
- ORACLE RETURNING 用法总结
ORACLE RETURNING 用法总结 场景 在存储过程.PL/SQL块里需要返回INSERT.DELETE.UPDATE.MERGE等DML语句执行后的信息时使用,合理使用returning能够 ...
- 2014/11/06 Oracle触发器初步 2014-11-06 09:03 49人阅读 评论(0) 收藏
触发器我就不多解释了,保证数据的完整性的神器,嗯..也是减少程序员工作托管给数据库操作的好帮手.就不讲一些大道理了.通俗点,我们对数据库的操作,无非就是增 删 改 查. 触发器就是在删,改,增的时候( ...
随机推荐
- R画图——分屏
最近项目需求,用R画了一个九宫格的图,第一次画,将简化后的脚本呈现一下,不是有人说,既然做了,那就摆出来吧. *中文行为说明: args <- commandArgs(T) 调用命令行读取 fi ...
- nyoj 51-管闲事的小明(遍历,比较)
51-管闲事的小明 内存限制:64MB 时间限制:4000ms Special Judge: No accepted:9 submit:20 题目描述: 某校大门外长度为L的马路上有一排树,每两棵相邻 ...
- zabbix4.0开源监控部署
---恢复内容开始--- 1.安装依赖环境 yum -y install telnet net-tools python-paramiko dejavu-sans-fonts python-setup ...
- CSS 技巧一则 -- 在 CSS 中使用三角函数绘制曲线图形及展示动画
最近一直在使用 css-doodle 实现一些 CSS 效果. css-doodle 是一个基于 Web-Component 的库.允许我们快速的创建基于 CSS Grid 布局的页面,以实现各种 C ...
- ubuntu安装应用日志
1.安装搜狗输入法,去官网下 2.安装vim 3.安装vbox5.16,导入win7(还未成功,报错UUID不匹配),改5.14试试 4.安装微信:http://www.cnblogs.com/Blu ...
- 【dp】Arrange the Schedule
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3538 题意:如题. 题解: 假如 一组数据 ...(n1)A.. ...
- spring、mybatis、事务项目整合,附完整代码和数据库文件
配置依赖项 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...
- href=”javascript:void(0);
href=”javascript:void(0);”这个的含义是,让超链接去执行一个js函数,而不是去跳转到一个地址,而void(0)表示一个空的方法,也就是不执行js函数. 为什么要使用href=” ...
- python2中的SSL:CERTIFICATE_VERIFY_FAILED错误的解决办法
在使用urllib2访问一个自签名的https链接时,对于python2.6以下版本,TLS握手期间是不会检查服务器X509的证书签名是否是CA的可信任根证书.不过python2.7以后改变了这种情况 ...
- 部署k8s集群监控Heapster
git clone https://github.com/kubernetes/heapster.gitkubectl apply -f heapster/deploy/kube-config/inf ...