- 浏览: 142946 次
- 性别:
- 来自: 浙江
文章分类
最新评论
-
bnmnba:
bnmnba 写道bnmnba 写道 三个文件的学习学习。这么 ...
linux下C/C++ 入门hello world(转) -
bnmnba:
bnmnba 写道 三个文件的学习学习。这么写:#includ ...
linux下C/C++ 入门hello world(转) -
bnmnba:
三个文件的学习学习。
linux下C/C++ 入门hello world(转) -
fcmfcm01:
个人觉得没什么必要,控制访问权限完全可以由方法来实现,就像ja ...
C#中属性和字段的区别和联系<转载> -
eagledame:
很详细 谢谢了~
JAVA IO流的老师小结
Oracle触发器详细介绍一
触发器
是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。
功能:
1、 允许/限制对表的修改
2、 自动生成派生列,比如自增字段
3、 强制数据一致性
4、 提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑
开始
create trigger biufer_employees_department_id
before insert or update
of department_id
on employees
referencing old as old_value
new as new_value
for each row
when (new_value.department_id<>80 )
begin
:new_value.commission_pct :=0;
end;
/
触发器的组成部分:
1、 触发器名称
2、 触发语句
3、 触发器限制
4、 触发操作
1、 触发器名称
create trigger biufer_employees_department_id
命名习惯:
biufer(before insert update for each row)
employees 表名
department_id 列名
2、 触发语句
比如:
表或视图上的DML语句
DDL语句
数据库关闭或启动,startup shutdown 等等
before insert or update
of department_id
on employees
referencing old as old_value
new as new_value
for each row
说明:
1、 无论是否规定了department_id ,对employees表进行insert的时候
2、 对employees表的department_id列进行update的时候
3、 触发器限制
when (new_value.department_id<>80 )
限制不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。
其中的new_value是代表更新之后的值。
4、 触发操作
是触发器的主体
begin
:new_value.commission_pct :=0;
end;
主体很简单,就是将更新后的commission_pct列置为0
触发:
insert into employees(employee_id,
last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )
values( 12345,’Chen’,’Donny’, sysdate, 12, ‘donny@hotmail.com’,60,10000,.25);
select commission_pct from employees where employee_id=12345;
触发器不会通知用户,便改变了用户的输入值。
触发器类型:
1、 语句触发器
2、 行触发器
3、 INSTEAD OF 触发器
4、 系统条件触发器
5、 用户事件触发器
注释:
before和after:指在事件发生之前或之后激活触发器。
instead of:如果使用此子句,表示可以执行触发器代码来代替导致触发器调用的事件。
insert、delete和update:指定构成触发器事件的数据操纵类型,update还可以制定列的列表。
referencing:指定新行(即将更新)和旧行(更新前)的其他名称,默认为new和old。
table_or_view_name:指要创建触发器的表或视图的名称。
for each row:指定是否对受影响的每行都执行触发器,即行级触发器,如果不使用此子句,则为语句级触发器。
when:限制执行触发器的条件,该条件可以包括新旧数据值得检查。
declare---end:是一个标准的PL/SQL块。
Oracle触发器详细介绍二--语句触发器
1、 语句触发器
是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。
例子:
需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。
Create table foo(a number);
Create trigger biud_foo
Before insert or update or delete
On foo
Begin
If user not in (‘DONNY’) then
Raise_application_error(-20001, ‘You don’t have access to modify this table.’);
End if;
End;
/
即使SYS,SYSTEM用户也不能修改foo表
[试验]
对修改表的时间、人物进行日志记录。
1、 建立试验表
create table employees_copy as select *from hr.employees
2、 建立日志表
create table employees_log(
who varchar2(30),
when date);
3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。
Create or replace trigger biud_employee_copy
Before insert or update or delete
On employees_copy
Begin
Insert into employees_log(
Who,when)
Values( user, sysdate);
End;
/
4、 测试
update employees_copy set salary= salary*1.1;
select *from employess_log;
5、 确定是哪个语句起作用?
即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?
可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词,作判断:
begin
if inserting then
-----
elsif updating then
-----
elsif deleting then
------
end if;
end;
if updating(‘COL1’) or updating(‘COL2’) then
------
end if;
[试验]
1、 修改日志表
alter table employees_log
add (action varchar2(20));
2、 修改触发器,以便记录语句类型。
Create or replace trigger biud_employee_copy
Before insert or update or delete
On employees_copy
Declare
L_action employees_log.action%type;
Begin
if inserting then
l_action:=’Insert’;
elsif updating then
l_action:=’Update’;
elsif deleting then
l_action:=’Delete’;
else
raise_application_error(-20001,’You should never ever get this error.’);
Insert into employees_log(
Who,action,when)
Values( user, l_action,sysdate);
End;
/
3、 测试
insert into employees_copy( employee_id, last_name, email, hire_date, job_id)
values(12345,’Chen’,’Donny@hotmail’,sysdate,12);
select *from employees_log
总结:语句级触发器.(语句级触发器对每个DML语句执行一次)是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。
实例:
create or replace trigger tri_test
after insert or update or delete on test
begin
if updating then
dbms_output.put_line('修改');
elsif deleting then
dbms_output.put_line('删除');
elsif inserting then
dbms_output.put_line('插入');
end if;
end;
Oracle触发器详细介绍三--行级触发器
行级触发器
本章介绍行级触发器机制。大部分例子以INSERT出发器给出,行级触发器可从insert update delete语句触发。
1、介绍
触发器是存储在数据库已编译的存储过程,使用的语言是PL/SQL,用编写存储过程一样的方式编写和编译触发器。下面在SQL*PLUS会话中创建和示例一个简单的Insert行级触发器。这个触发器调用DBMS_OUTPUT在每插入一行数据时打印“executing temp_air”
SQL> set feedback off
SQL> CREATE TABLE temp (N NUMBER);
SQL> CREATE OR REPLACE TRIGGER temp_air
2 AFTER INSERT ON TEMP
3 FOR EACH ROW
4 BEGIN
5 dbms_output.put_line('executing temp_air');
6 END;
7 /
8 SQL> INSERT INTO temp VALUES (1); -- insert 1 row
executing temp_air
SQL> INSERT INTO temp SELECT * FROM temp; -- insert 1 row
executing temp_air
SQL> INSERT INTO temp SELECT * FROM temp; -- inserts 2 rows
executing temp_air
executing temp_air
SQL>
尽管第三个Insert语句是一条SQL语句,但插入TEMP表中两条记录。许多insert语句插入一条记录,但可以用一条语句插入许多行。
2、行级触发器语法:
CREATE OR REPLACE TRIGGER trigger_name
AFTER|BEFORE INSERT|UPDATE|DELETE ON table_name
FOR EACH ROW
[WHEN (Boolean expression)]
DECLARE
Local declarations
BEGIN
Trigger Body written PL/SQL
END;
·Trigger_name
用触发器名来确定表名和触发器类型。PL/SQL运行时错误将产生一个PL/SQL错误信息,涉及触发器名和行数。下面Oracle错误显示了在students表上的AFTER-INSERT行触发器的第5行有一个被0除错误。
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.STUDENTS_AIR", line 5
ORA-04088: error during execution of trigger
'SCOTT.STUDENTS_AIR'
行记数从关键字DECLARE行开始,如果没有DECLARE部分,BEGIN语句是第一行。触发器名称存储在USER_TRIGGERS表的TRIGGER_NAME。触发器名一般由表名、触发器类型、触发事件,语法如下:
trigger_name = table_name_[A|B] [I|U|D] [R|S]
trigger_name 最长30个字符,所以有时不得不使用表名缩写。常表名一般要有一个规则的缩写。这样可以减少故障分析处理时间。
[A|B] 表示是AFTER 或 BEFORE 触发器类型
[I|U|D] 表示触发事件,可能是 insert ,update 或者delete
[R|S] 表示行级(row)或语句级(statement)触发器类型。
·BEFORE|AFTER insert on table_name
这条语句告诉Oracle什么时候执行触发器.它可能在ORACLE 完整性约束检查前或后执行,可以指定一个Before或after触发器在多语句操作类型上触发,如:
BEFORE INSERT OR UPDATE on table_name
BEFORE INSERT OR UPDATE OR DELETE on table_name
AFTER INSERT OR DELETE on table_name
DBMS_STANDARD 包提供了四个boolean函数来区分SQL语句类型。
PACKAGE DBMS_STANDARD IS
FUNCTION inserting RETURN BOOLEAN;
FUNCTION updating RETURN BOOLEAN;
FUNCTION updating (colnam VARCHAR2) RETURN BOOLEAN;
FUNCTION deleting RETURN BOOLEAN;
etc,
END DBMS_STANDARD;
在触发器中可以直接使用函数名称,不需要指定包名:
CREATE OR REPLACE TRIGGER temp_aiur
AFTER INSERT OR UPDATE ON TEMP
FOR EACH ROW
BEGIN
CASE
WHEN inserting THEN
dbms_output.put_line
('executing temp_aiur - insert');
WHEN updating THEN
dbms_output.put_line
('executing temp_aiur - update');
END CASE;
END;
对于Update行级触发器,可以指定被更新的列作为触发器触发条件。
CREATE OR REPLACE TRIGGER temp_aur
AFTER INSERT OR UPDATE OF M, P ON TEMP
FOR EACH ROW
BEGIN
dbms_output.put_line
('after insert or update of m, p');
END;
·WHEN(BOOLEAN EXPRESSION)
这是个可选语句,用来过滤触发触发器的条件。
CREATE OR REPLACE TRIGGER temp_air
AFTER INSERT ON TEMP
FOR EACH ROW
WHEN (NEW.N = 0)
BEGIN
dbms_output.put_line('executing temp_air');
END;
上例中表示AFTER INSERT行触发器触发的条件是:N字段的值等于0.
NEW.COLUMN_NAME : INSERT或UPDATE触发器中WHEN语句中引用字段的语法。
OLD.COLUMN_NAME : 用于UPDATE或DELETE行级触发器中WHEN语句中。在INSERT语句中为Null。
Oracle触发器详细介绍四--INSTEAD OF触发器
在简单视图上往往可以执行INSERT、UPDATE和DELETE操作,但是在复杂视图上执行INSERT、UPDATE和DELETE操作是有限的。如果视图子查询包含有集合操作符、分组函数、DISTINCT关键字或者连接查询,那么将禁止在该视图上执行DML操作。为了在这些复杂视图上执行操作,需要建立INSTEAD-OF触发器。INSTEAD-OF触发器具有以下限制:
INSTEAD OF触发器只适用于视图。
INSTEAD OF触发器不能指定BEFORE和AFTER选项。
不能在具有WITH CHECK OPTION选项的视图上建立INSTEAD OF触发器。
INSTEAD OF触发器必须包含有FOR EACH ROW选项。
复杂视图DEPT_EMP用于显示部门号、部门名、雇员号以及雇员名,并且在该复杂视图上不能执行任何DML操作。为了在该视图上执行DML操作,必须建立 INSTEAD OF触发器。下面以完成该认务为例,说明建立INSTEAD OF触发器的方法。在建立INSTEAD OF触发器之前,首先建立视图DEPT_ENP。
create or replace view dept_emp as
select a.deptno,a.dname,b.empno,b.ename from department a,employee b
where a.deptno=b.deptno;
create or replace trigger tr_instead_of_dept_emp
instead of insert on dept_emp for each row
declare
v_temp int;
begin
select count(*) into v_temp from department where deptno=:new.deptno;
if v_temp=0 then
insert into department(deptno,dname) values(:new.deptno,:new.dname);
end if;
select count(*) into v_temp from employee where empno=:new.empno;
if v_temp=0 then
insert into employee(empno,ename,deptno) values(:new.emptno,:new.deptno);
end if;
end;
/
Oracle触发器详细介绍五--系统事件触发器
oracle的系统事件触发器:系统事件触发器是指基于oracle系统事件(如logon和startup)所建立的触发器。通过这种触发器可以跟踪系统或数据库的变化。
create table jax_event_table(eventname varchar2(30),time date);
createtrigger tr_startup
after startup ondatabase
begin
insertinto jax_event_table values(ora_sysevent,sysdate);
end;
createtrigger tr_shutdown
beforeshutdownondatabase
begin
insertinto jax_event_table values(ora_sysevent,sysdate);
end;
在建立如上所示的两个触发器后,使用shutdown和startup关闭开启数据库会往表jax_event_table中记录一条记录,但 shutdown abort则不会触发该触发器,而startup nomount后使用alter database将数据库更改为mount或者open都只会触发一次。
1 SHUTDOWN 2008-3-20 14:29:47
2 STARTUP 2008-3-20 14:42:52
3 SHUTDOWN 2008-3-20 14:43:06
4 STARTUP 2008-3-20 14:45:34
登录和退出触发器用来记载登录用户名称、时间和ip地址
createtable jax_log_table(
username varchar2(20), log_time date, onoff varchar(6),address varchar2(30));
createtrigger tr_logon
after logon ondatabase
begin
insertinto jax_log_table values(ora_login_user,sysdate,'logon',ora_client_ip_address);
end;
createtrigger tr_logoff
before logoff ondatabase
begin
insertinto jax_log_table values(ora_login_user,sysdate,'logoff',ora_client_ip_address);
end;
select * from jax_log_table;
1 SYS 2008-3-20 14:55:17 logon
2 SYSMAN 2008-3-20 14:55:21 logon
3 SYS 2008-3-20 14:55:45 logon 127.0.0.1
4 SYS 2008-3-20 14:56:07 logoff
5 SYSMAN 2008-3-20 14:56:26 logon
6 SYSMAN 2008-3-20 14:56:27 logoff
7 ZHANGLEI 2008-3-20 14:56:35 logon 127.0.0.1
8 ZHANGLEI 2008-3-20 14:57:01 logoff
9 SYS 2008-3-20 14:57:12 logon 127.0.0.1
10 SYSMAN 2008-3-20 14:57:31 logon
11 SYSMAN 2008-3-20 14:57:32 logoff
DDL触发器记录系统所发生的DDL事件(create,alter,drop等)
createtable jax_event_ddl_table(event varchar2(20),
username varchar2(10),owner varchar2(10),objname varchar2(20),
objtype varchar2(10),timedate);
createtrigger tr_ddl
afterddlondatabase
begin
insertinto jax_event_ddl_table values(ora_sysevent,ora_login_user,
ora_dict_obj_owner,ora_dict_obj_name,ora_dict_obj_type,sysdate)
end;
1 CREATE SYS SYS T2 TABLE 2008-3-20 15:05:41
2 CREATE SYS SYS VIEW_T2 VIEW 2008-3-20 15:06:53
由上面的描述看到,在编写系统事件触发器时,应用开发人员经常需要使用事件属性函数。常用的事件属性函数如下:
Ora_client_ip_address 返回客户端的ip地址
Ora_database_name 返回当前数据库名
Ora_des_encrypted_password 返回des加密后的用户口令
Ora_dict_obj_name 返回ddl操作所对应的数据库对象名
Ora_dict_obj_name_list(name_list out ora_name_list_t) 返回在事件中被修改的对象名列表
Ora_dict_obj_owner 返回ddl操作所对应的对象的所有者名
Ora_dict_obj_owner_list(owner_list out ora_name_list_t) 返回在事件中被修改的对象的所有者列表
Ora_dict_obj_type 返回ddl操作所对应的数据库对象的类型
Ora_grantee(user_list out ora_name_list_t) 返回授权事件的授权者
Ora_instance_num 返回例程号
Ora_is_alter_column(column_name in varchar2) 检测特定列是否被修改
Ora_is_creating_nested_table 检测是否正在建立嵌套表
Ora_is_drop_column(column_name in varchar2) 检测特定列是否被删除
Ora_is_servererror(error_number) 检测是否返回了特定oracle错误
Ora_login_user 返回登录用户名
Ora_sysevent 返回触发器的系统事件名。
发表评论
-
vim 常用命令
2010-10-29 14:55 681vim(vi)是Linux中功能强大的编辑工具。vim有3中主 ... -
SQL_oracle测试及答案
2009-07-25 19:25 789--学生表 cr ... -
SQL_网上PLSQL
2009-07-25 19:24 2335PL/SQL教程 课程 一 PL/SQL 基本查询与排序 ... -
SQL_中的CASE WHEN使用
2009-07-20 21:13 3037SQL中的CASE WHEN使用Case具有两种格式。简单Ca ... -
SQL以及PLSQL上课重点代码
2009-07-19 14:38 8961\select cname , nvl(s.scid,0)f ... -
SQL_oracle外连接
2009-07-19 14:37 7392009-06-23oracle外连接关键字: oracle ... -
SQL_Oracle数据类型简介
2009-07-19 14:36 1186一、概述 在ORACLE8中定义了:标量(SCALAR)、 ... -
SQL_oracle串讲
2009-07-19 14:35 971Oracle串讲 一、查询语句 1.SELECT 语法: S ... -
SQL_oracle_rownum介绍
2009-07-19 14:34 1179rownum介绍:http://hi.baidu.com/ra ... -
SQL_DDL_DML_DCL的介绍
2009-07-19 14:33 1303DDL is Data Definition Language ... -
Linux Jobs等前后台运行命令解
2009-07-19 14:32 4764http://hi.baidu.com/seeseeabc/b ...
相关推荐
Oracle_Trigger_及_Oracle_常见问题解决方法 Oracle_Trigger_及_Oracle_常见问题解决方法
sql参考手册+oracle触发器与存储过程高级编程,其中sql参考手册包含了t-sql参考、jet-sql参考和oracle-sql参考。
查询ORACLE 系统中当前会话正在执行的有关SQL语句。
ORACLE PL/SQL 存储过程 触发器 ORACLE PL/SQL 存储过程 触发器 子程序 游标
Oracle触发器与pl/sql存储过程编程 chm格式的
oracle数据库服务器的核心概念:数据库表、索引、表空间、约束、触发器、pl/sql以及如何使用PL/SQL触发器和存储过程。
ORACLE PL_SQL编程之八:把触发器说透,ORACLE PL_SQL编程之八:把触发器说透ORACLE PL_SQL编程之八:把触发器说透ORACLE PL_SQL编程之八:把触发器说透ORACLE PL_SQL编程之八:把触发器说透
在触发器中,需要用到 SQL Server 的 inserted 和 deleted 两个虚拟表,在执行 sql 命令时,这两个虚拟表分别记录的内容如下: sql命令 deleted inserted ------------------------------------------------...
oracle pl/sql 存储过程和函数与触发器
在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块。 触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个...
本书重点阐述了Oracle数据库服务器的核心概念:数据库表,索引,表空间,约束,触发器,PL/SQL. 本书针对程序员而编著,掌握一定编程知识会对学习本书有所帮助,但不是必需的。
ORACLE数据库SQL*Forms触发器的应用研究.pdf
一键生成Oracle自增序列和触发器,方便Oracle sql的编写加快代码编写速度。
oracle 增加序列 触发器 全过程 sql文件只需更换表名
Oracle触发器文章配套建表语句。库存明细表:e_stock_info。销售明细表:e_sales_info(这里创建的是按日自动分区表)。
SQLSERVER转ORACLE->SQLSERVER转ORACLE语句写法、SQLSERVER转ORACLE语句写法
单行查询 分组查询 多表查询 子查询 高级查询 高级查询 数据字典 约束 视图 索引 游标 函数 存储过程 触发器 事务管理 用户管理 备份 恢复
oracle触发器与存储过程高级编程文档,详细讲解了PL/SQL语言,以及ORACLE的一些高级用法。平时学校教学中完全没有见过的东西里面都有。觉得值得下!
第一章 PL/SQL 程序设计简介 4 §1.2 SQL与PL/SQL 4 §1.2.1 什么是PL/SQL? 4 §1.2.1 PL/SQL的好处 4 §1.2.2 PL/SQL 可用的SQL语句 5 §1.3 运行PL/SQL程序 5 第二章 PL/SQL块结构和组成元素 6 §2.1 PL/SQL块 6 ...
这一部分概述了 Transact-SQL 和 PL/SQL 语言语法之间的相同点和不同点,并给出转换策略。 要将 Oracle DML 语句和 PL...9. 把 PL/SQL 触发器转换为 Transact-SQL 触发器。 10. 使用 SET SHOWPLAN 语句,优化查询性能。