- 浏览: 1046228 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
nieanan:
感谢,很有帮助。
eclipse 改变JAVA_HOME路径 -
Orange_killer:
写的什么东西,文不对题
Hibernate Search大数据量手动建立索引 -
xiaoasha:
org.eclipse.equinox.servlet.api ...
《OSGI实战》遇到的问题 -
powertech:
写的挺细,有用!
SyntaxError: Non-ASCII character Python、Unicode和中文 -
huang_yong:
public class XMLUtil {
pri ...
XStream 去除生成的XML节点的class="list"
语句级触发器
我们先看一个AFTER-INSERT-STATEMENT触发器:
CREATE OR REPLACE TRIGGER temp_ais
AFTER INSERT ON TEMP
BEGIN
dbms_output.put_line('executing temp_ais');
END;
看一下下面语句的结果:
SQL> set feedback off
SQL> INSERT INTO temp VALUES (1); -- insert 1 row
executing temp_ais
SQL> INSERT INTO temp VALUES (1); -- insert 1 row
executing temp_ais
SQL> INSERT INTO temp SELECT * FROM temp; -- insert 2 rows
executing temp_ais
每个SQL插入语句将触发一次,行级触发器最后一条语句要触发两次。
一、事件顺序
用Insert 语句级触发器可以做:
·可以在表上执行一个合计运算,可以在insert前或后来计算。
·可以使用语句级触发器去处理行级触发器控制的数据。
·可以给事件发信号。可以仅仅是一个打印语句。也可以是一个email或使用DBMS_ALERT包向其他处理过程发送信号。
Tasks Performed
Stages -------------------
---------------------------------- ———> | Rehect the |
Fires once | BIS function | | Transaction |
per statement | Statement Level Trigger | -------------------
----------------------------------- ———> -------------------
| | Take Action |
| -------------------
insert |
3行记录 | -------------------------- |
————> | | Row Trigger | | -------------------------------
————> | -------------------------- | |每一个行触发器插入一|
————> | | | |行触发一次,插入三行|
| ---------------------------------------- | |触发三次,语句级触发|
| | Oracle enforces constraints | | |器在行操作和行数据上|
| ---------------------------------------- | |不可见 |
| | | | |
| -------------------------- | -------------------------------
| | Row Trigger | |
| -------------------------- |
|
| ----------------------
---------------------------------- ————> | Rehect the |
Fires once | AIS function | | Transaction |
per statement | Statement Level Trigger | ---------------------
---------------------------------- ————> --------------------
| Take Action |
--------------------
上图显示了语句级出发器的行为。同时也显示了在Before statement触发器和After statement触发器间的行级触发器的触发情况。如果一个update SQL语句更新三行,那么行级触发器触发三次,语句级触发器触发一次。
二、insert 语句级触发器定义语法
语法如下:
CREATE OR REPLACE TRIGGER trigger_name
[AFTER | BEFORE] INSERT ON table_name
DECLARE
Local declarations
BEGIN
Body written PL/SQL
END;
语句级和行级触发器在语法上关键的不同在于:FOR EACH ROW字句。在行级触发器中指定这个子句而语句级触发器中不需要指定。
1)、WHEN(Boolean expression) 所有行触发器可用
2)、OF column_name clause 仅对update触发器可用
在语句级触发器中:
·引用:NEW.COLUMN_NAME and :OLD.COLUMN_NAME是不正确的。
·不能使用When(boolean expression)子句中包含OLD.COLUMN_NAME和 NEW.COLUMN_NAME.
可以使用下面的语句:
CREATE OR REPLACE TRIGGER temp_biuds
BEFORE INSERT OR UPDATE OR DELETE ON TEMP
BEGIN
CASE
WHEN inserting THEN
PL/SQL code here
WHEN updating THEN
PL/SQL code here
WHEN deleting THEN
PL/SQL code here
END CASE;
END;
三、语句级组合
·使用错误码来更新Errors包
·包商业规则逻辑放到一个约束包中
·编写before或after语句级触发器
1)、第一步是声明错误码和错误信息。Errors包更新包含了-20002和-2003两个错误码
CREATE OR REPLACE PACKAGE errors IS
eng_dept_sal CONSTANT PLS_INTEGER := -20001;
app_error_02 CONSTANT PLS_INTEGER := -20002;
app_error_03 CONSTANT PLS_INTEGER := -20003;
eng_dept_sal_txt CONSTANT VARCHAR2(100) :=
'The salary exceeds the ENGL maximum of $10,000.00';
app_error_02_txt CONSTANT VARCHAR2(100) :=
'No additions if the budget exceeds $55,000.00';
app_error_03_txt CONSTANT VARCHAR2(100) :=
'Budget cannot be over $60,000.00';
END errors;
2)、把商业逻辑封装在约束包中。
CREATE OR REPLACE PACKAGE professors_cons IS
PROCEDURE constrain_budget
(limit NUMBER,err_code PLS_INTEGER,err_text
VARCHAR2);
END professors_cons;
CREATE OR REPLACE PACKAGE BODY professors_cons IS
PROCEDURE constrain_budget
(limit NUMBER,err_code PLS_INTEGER,err_text
VARCHAR2)
IS
budget_sum NUMBER;
BEGIN
SELECT SUM(salary) INTO budget_sum FROM
professors;
IF budget_sum > limit THEN
RAISE_APPLICATION_ERROR(err_code, err_text);
END IF;
END constrain_budget;
END professors_cons;
3)、定义before和after触发器
CREATE OR REPLACE TRIGGER professors_bis
BEFORE INSERT OR UPDATE ON professors
BEGIN
professors_cons.constrain_budget
(55000, errors.budget_err_1,
errors.budget_err_1_txt);
END;
CREATE OR REPLACE TRIGGER professors_ais
AFTER INSERT OR UPDATE ON professors
BEGIN
professors_cons.constrain_budget
(60000, errors.budget_err_2,
errors.budget_err_2_txt);
END;
四、处理行获得的数据
行级触发器可以在全局临时表中存储:OLD 和 :NEW 字段值。全局临时表范围仅是事务。通过复制:OLD 和 :NEW 值,商业规则的处理被延期到语句级触发器上。有时是必须的,因为商业规则是复杂的,需要从表中查询,包括表被更新。
1)、首先需要一个全局临时表,它在行级触发器上用于存储数据。
CREATE global temporary TABLE professors_g
(prof_name VARCHAR2(10),
specialty VARCHAR2(20),
hire_date DATE,
salary NUMBER(7,2),
tenure VARCHAR2(3),
department VARCHAR2(10)) ON COMMIT DELETE ROWS;
2)、为这张表编写存储过程,放于包Professors_cons里.如下:
CREATE OR REPLACE PACKAGE professors_cons IS
PROCEDURE load_temp_table
(v_prof_name professors.prof_name%TYPE,
v_specialty professors.specialty%TYPE,
v_hire_date professors.hire_date%TYPE,
v_salary professors.salary%TYPE,
v_tenure professors.tenure%TYPE,
v_department professors.department%TYPE);
PROCEDURE dump_temp_table;
END professors_cons;
包体为:
CREATE OR REPLACE PACKAGE BODY professors_cons IS
PROCEDURE load_temp_table
(v_prof_name professors.prof_name%TYPE,
v_specialty professors.specialty%TYPE,
v_hire_date professors.hire_date%TYPE,
v_salary professors.salary%TYPE,
v_tenure professors.tenure%TYPE,
v_department professors.department%TYPE)
IS
BEGIN
INSERT INTO professors_g VALUES
(v_prof_name, v_specialty, v_hire_date,
v_salary, v_tenure, v_department);
END load_temp_table;
PROCEDURE dump_temp_table IS
BEGIN
FOR rec in (SELECT * FROM professors_g) LOOP
dbms_output.put_line(
rec.prof_name||' '||rec.specialty||' '||
rec.hire_date||' '||rec.salary||' '||
rec.tenure||' '||rec.department);
END LOOP;
END dump_temp_table;
END professors_cons;
3)、下面是一个after delete 行触发器。当它触发时,通过Professors_cons插入临时表一行数据。
CREATE OR REPLACE TRIGGER professors_adr
AFTER DELETE ON professors
FOR EACH ROW
BEGIN
professors_cons.load_temp_table
(:old.prof_name, :old.specialty, :old.hire_date,
:old.salary, :old.tenure, :old.department);
END;
下一个是after delete语句级触发器,使用约束包打印删除的行信息。
CREATE OR REPLACE TRIGGER professors_ads
AFTER DELETE ON professors
BEGIN
professors_cons.dump_temp_table;
END;
delete SQL语句后面是语句级触发器的输出:
SQL> DELETE FROM professors;
Blake Mathematics 08-aug-2003 02:06:27 10000 YES MATH
Milton Am Hist 09-aug-2003 02:06:27 10000 YES HIST
Wilson English 06-aug-2003 02:06:27 10000 YES ENGL
Jones Euro Hist 12-jul-2003 02:06:28 10000 YES HIST
Crump Ancient Hist 12-jul-2003 02:06:28 10000 YES HIST
5 rows deleted.
发表评论
-
MySQL 5.1 无法启动 1067 错误解决方法
2010-07-13 23:06 2647MySQL 5.1 无法启动 1067 错误解决方法 这两天 ... -
连接VMWare上的oracle
2010-07-05 10:55 1609在vmware上面安装了一个oracle,主机却怎么也连接不 ... -
oracle-merge用法详解
2010-01-26 14:10 1084原文:http://blog.chinaunix.net/u/ ... -
数据库与数据仓库的区别
2010-01-19 12:38 1302简而言之,数据库是面向事务的设计,数据仓库是面向主题设计的。 ... -
oracle 判断字段中的中文的方法
2010-01-18 15:30 5207判断字段中的中文的方法,与oracle的字符集有关, AL32 ... -
从 char 数据类型到 datetime 数据类型的转换导致 datetime 值越界
2010-01-11 10:04 2728想要造一点随机数据,日期等于ID%30,结果却碰到了:“从 ... -
oracle 与 SQL Server 利用select 建表和update的区别
2010-01-05 14:47 2407Oracle: 建表可以使用: crea ... -
筛选数据库重复记录
2010-01-05 11:07 2703请问以下两个功能如何实现? (1)如何选出重复的 ... -
调用oracle10g 存储过程利用sys_refcursor返回结果集
2009-12-23 12:16 4910SQL> create table test 2 ... -
ORACLE中有没有判断一个字符串是否可以转换成数字的函数
2009-12-23 09:56 3847Org: http://topic.csdn.net/t/20 ... -
ORACLE存储过程update不成功的另一个原因
2009-12-11 10:45 5273今天,一个存储过程遇到了一个奇怪的问题,没有任何的出错信息,但 ... -
oracle存储过程调用
2009-12-02 15:24 2706今天写了一个存储过程,发现PL/SQL里面这个存储过程图标上老 ... -
聚族索引、非聚族索引、组合索引的含义和用途
2009-11-26 10:48 2352一、什么是索引 索引可以理解为我们小时候使用 的汉语字典的 ... -
mssql附加数据库后出现“对象名XXXX无效”
2009-11-19 16:48 5390mssql数据库服务器进行硬件升级后,采用附加数据库的方式还原 ... -
换种方法,提高left join查询的效率
2009-09-28 15:11 4537表之间使用联结查询时,以left join为例,当联结的表较多 ... -
char,varchar,nvarchar有什么区别
2009-09-25 13:08 1393一 、 nchar 和 nvarc ... -
Oracle索引与where
2009-09-24 12:24 1341一个ORACLE查询中,有N多的查询条件,要把:一次可以缩小范 ... -
大数据量分页存储过程效率测试附代码
2009-09-24 11:17 1599原文地址:http://www.cnblogs.com/Jos ... -
SQLServer 实现rownum 的功能
2009-09-10 10:39 7915方法1: with temp as ( sel ... -
ORACLE中用rownum分页并排序的SQL语句
2009-09-10 10:37 1610以前分页习惯用这样的SQL语句: select * ...
相关推荐
调试oracle触发器文档,自己整理的,不懂的可以聊系我
1、行级触发器不支持 update 、select 、delete 对自身表的操作。 2、表级触发器 不支持 :new 和 :old对象 所以想要触发器对自身表数据做修该,则用行级触发器得到 :new 和 :old对象中的相关数据,然后将这样的数据...
个人亲测oracle触发器调用java程序
oracle insert数据成功之后调用触发器,触发器调用存储过程,存储实时调用java http
oracle触发器功能介绍内附具体说明和简单介绍
oracle_触发器的种类和触发事件,很详细!
oracle触发器语法要点
介绍数据库触发器的PPT。内容包括:存储过程的创建与使用;存储过程的查看、编辑和删除;触发器的创建与使用;触发器的查看、编辑、重命名和删除
oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例 oracle数据库触发器实例
Oracle 触发器 备份 表数据
利用oracle 系统触发器防止用户使用drop table 或truncate table 命令。
触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。数据库触发器有以下的作用:
ORACLE触发器、内置程序包教学.doc )
oracle 触发器 调用 存储过程 Oracle自治事务(Autonomous Transaction)
Oracle触发器与存储过程高级编程Oracle触发器与存储过程高级编程
Oracle触发器的概念和类型
oracle触发器与存储过程高级编程
详细整理了oracle中before和after的使用问题
oracle触发器执行顺序.pdf
本文介绍了Oracle触发器的使用心得。