oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)
创建触发器
触发器类似于过程和函数,都拥有声明、执行和异常处理过程的带名PL/SQL块。与包类似,触发器必须存储在数据库中。
前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数。与之相反,触发器是在事件发生时隐式地运行的,并且触发器不能接受参数。
运行触发器的方式叫做激发(firing)触发器。
触发事件可以是对数据库表的DML(INSERT、UPDATE、DELETE)操作或某种视图的操作。Oracle8i把触发器功能扩展到了可以激发系统事件,如数据库的启动和关闭,以及某种DDL操作。
触发器主要分为:DML触发器、替代触发器和系统触发器。本次课程主要讲述DML触发器。
触发器可用来补充声明的参照完整性,强制实施复杂的业务规则。
触发器是一个独立的事务,被当作一个整体执行,在执行过程中如果发生错误,则整个事务会自动回滚。
DML触发器由DML(INSERT、UPDATE、DELETE)语句激发。
创建DML触发器语法:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER} triggering_event ON table_reference
[FOR EACH ROW [WHEN trigger_condition]]
trigger_body;
trigger_name是触发器名,triggering_event指定了何时激发触发器, table_reference是定义触发器的表, trigger_body是触发器的主要处理代码。WHEN子句的trigger_condition如果被使用的话,将首先进行求值。触发器的主体仅当此条件求值为TRUE时才被执行
触发器的激发顺序
执行BEFORE语句级触发器(如果有的话)。
对于受语句影响的每一行:
执行BRFORE行级触发器(如果有的话)。(for each row)
执行DML语句
执行AFTER行级触发器(如果有的话)。
执行AFTER语句级触发器(如果有的话)。
实例
CREATE OR REPLACE TRIGGER tri_emp_stmBefore
BEFORE INSERT ON EMP
BEGIN
dbms_output.put_line('Before Statement trigger');
END;
CREATE OR REPLACE TRIGGER tri_emp_stmAfter
after INSERT ON EMP
BEGIN
dbms_output.put_line('After Statement trigger');
END;
CREATE OR REPLACE TRIGGER tri_emp_rowBefore
before INSERT ON EMP
for each row
BEGIN
dbms_output.put_line('Beore row trigger');
END;
CREATE OR REPLACE TRIGGER tri_emp_rowAfter
after INSERT ON EMP
for each row
BEGIN
dbms_output.put_line('After row trigger');
END;
创建语句级触发器: Example
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT ON emp
BEGIN
IF (TO_CHAR(SYSDATE, 'DY') IN ('星期六', '星期天'))
OR (TO_CHAR(SYSDATE, 'HH24:MI') NOT BETWEEN '08:00' AND '18:00')
THEN
RAISE_APPLICATION_ERROR (-20500, 'You may insert into EMP table only during business hours.');
END IF;
END;
创建语句级触发器: 测试上述触发器
SQL>INSERT INTO emp (empno, ename,hiredate,job, sal, deptno)
VALUES (300,'Smith Rob',SYSDATE,'IT_PROG', 4500, 60)
创建行级触发器: Example
CREATE OR REPLACE TRIGGER restrict_salary
BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW
BEGIN
IF NOT (:NEW.job IN ('AD_PRES', 'AD_VP')) AND :NEW.sal > 15000
THEN
RAISE_APPLICATION_ERROR (-20202, 'Employee cannot earn this amount');
END IF;
END;
创建行级触发器: 测试上述触发器
SQL> UPDATE emp
SET sal = 15500
WHERE ename = 'SMITH';
在行级触发器中使用 :old和 :new
触发语句所处理的每一行都激发一次行级触发器。在触发器的内部,你可以访问当前正在被处理的行。这是通过“伪记录”——:old和:new实现的。它们的类型是table_reference%ROWTYPE
在行级触发器中使用 :old和 :new
create or replace TRIGGER GenerateStudentID
BEFORE INSERT ON t_student
FOR EACH ROW
BEGIN
SELECT seq_student_id.NEXTVAL
INTO :new.n_student_ID
FROM dual;
END GenerateStudentID;
执行上述触发器
SQL>INSERT INTO students (first_name, last_name)
VALUES ('Lolita', 'Lazarus');
SQL>INSERT INTO students (ID, first_name, last_name)
VALUES (-7, 'Zelda', 'Zoom');
在行级触发器中使用限制条件
创建替代触发器
替代触发器只能定义在视图上
CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF
event1 [OR event2 OR event3]
ON view_name
[REFERENCING OLD AS old | NEW AS new]
[FOR EACH ROW]
trigger_body
实例
CREATE TABLE new_emps AS
SELECT empno, ename, sal, deptno, job, hiredate FROM emp;
CREATE TABLE new_depts AS
SELECT d.deptno, d.dname, d.loc,sum(e.sal) tot_dept_sal
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP BY d.deptno, d.dname, d.loc;
CREATE VIEW emp_details AS
SELECT e.empno, e.ename, e.sal, e.deptno,e.job, d.dname, d.loc
FROM emp e, dept d
WHERE e.deptno = d.deptno;
管理触发器()
删除触发器 DROP TRIGGER secure_emp;
oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)的更多相关文章
- oracle PL/SQL(procedure language/SQL)程序设计
PL/SQL(procedure language/SQL)语言是Oracle对SQL语言的过程化扩充,是一个完整的编程语言.PL/SQL实现了过程化语句(如分支.循环等)与SQL语句的无缝连接,将过 ...
- Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)
1.PL/SQL是一种高级数据库程序设计语言,专门用于在各种环境下对Oracle数据库进行访问.该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理. 2.PL/SQL是对SQ ...
- oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)
什么是异常?在PL/SQL中的一个标识.在程序运行期间被触发的错误.异常是怎样被触发的?产生一个Oracle错误.用户显示触发.怎样处理异常?用异常处理句柄捕获异常.传播异常到调用环境. 捕获异常 E ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象BEGIN (必须) 执行语句EXCEPTION (可选) 错误处理语句END; (必须)匿名块( ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包(转)
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象 BEGIN (必须) 执行语句 EXCEPTION (可选) 错误处理语句 END; (必 ...
- oracle PL/SQL(procedure language/SQL)程序设计之游标cursors
游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...
- oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)
在PL/SQL程序中,允许使用的SQL语句只有DML和事务控制语句,使用DDL语句是非法的.使用SELECT语句从数据库中选取数据时,只能返回一行数据.使用COMMIT, ROLLBACK, 和SA ...
- oracle PL/SQL(procedure language/SQL)程序设计--控制结构(if else )
IF逻辑结构:IF-THEN-END IFIF-THEN-ELSE-END IFIF-THEN-ELSIF-END IF 语法 IF condition THEN statements;[ELSIF ...
- oracle PL/SQL(procedure language/SQL)程序设计(续集)之PL/SQL函数
PL/SQL函数 examples:“ 构造一个邮件地址 v_mailing_address := v_name||CHR(10)|| ...
随机推荐
- StringBuffer与StringBuilder的异同
一. 相同之处 1.均是可变字符序列,可以随机的改变字符串,如追加操作或插入操作 2. 均使用了内部缓冲区,并且当内部缓冲区溢出后均会自动增大 二. 不同之处 1. Stri ...
- spring事物配置注意事项
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx ...
- [添加用户]解决useradd 用户后没有添加用户Home目录的情况,Linux改变文件或目录的访问权限命令,linux修改用户密码
将nobody用户添加到nogroup 组:usermod -g nogroup nobody cat /etc/passwd|grep nobodynobody:x:65534:65534:nobo ...
- Oracle中wm_concat()函数的使用
Oracle中wm_concat()函数的使用 wm_concat()函数是oracle行列转换函数,该函数可以把列值以‘,’分割开来,并显示成一行. 1.原数据: 2.把结果分组以‘|’分隔,以一行 ...
- Oracle中TO_DATE格式
转自:http://www.cnblogs.com/ajian/archive/2009/03/25/1421063.html TO_DATE格式(以时间:2007-11-02 13:45:25为 ...
- openNebula 模板实例化成虚拟机【参数名为VM_NAME】
{ "action": { "perform": "instantiate", "params": { "vm ...
- 常见错误:Apple Mach-O Linker Error
常见错误描述: Apple Mach-O Linker Error这类错误的错误信息最后一行通常如下: Command /Developer/Platforms/iPhoneOS.platform/D ...
- Cortex-M3 Context Switching
http://www.embedded.com/design/embedded/4231326/Taking-advantage-of-the-Cortex-M3-s-pre-emptive-cont ...
- SaundProgressBar
https://github.com/eltld/SaundProgressBar
- [AngularJS] Accessing Data in HTML -- controllerAs, using promises
<!DOCTYPE html> <html> <head> <title>Access Data From HTML</title> < ...