功能:
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、 用户事件触发器
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
update employees_copy set salary=50000 where employee_id =
12345;
2、 行触发器
是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外:

1、 定义语句中包含FOR EACH ROW子句
2、 在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。

比如:
定义:
create trigger biufer_employees_department_id
before
insert or update
of department_id
on employees_copy
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;
/
Referencing 子句:
执行DML语句之前的值的默认名称是 :old ,之后的值是 :new

insert 操作只有:new
delete 操作只有 :old
update 操作两者都有

referencing子句只是将new 和old重命名为new_value和old_value,目的是避免混淆。比如操作一个名为
new的表时。

作用不很大。
[试验]:为主健生成自增序列号
drop table foo;
create table foo(id
number, data varchar2(20));
create sequence foo_seq;
create or replace
trigger bifer_foo_id_pk
before insert on foo
for each row
begin

select foo_seq.nextval into :new.id from dual;
end;
/
insert
into foo(data) values(‘donny');
insert into foo values(5,'Chen');
select
* from foo;
3、 INSTEAD OF 触发器更新视图
Create or replace
view company_phone_book as
Select first_name||', '||last_name name, email,
phone_number,
employee_id emp_id
From hr.employees;
尝试更新email和name

update hr.company_phone_book
set name='Chen1, Donny1'
where
emp_id=100
create or replace trigger update_name_company_phone_book

INSTEAD OF
Update on hr.company_phone_book
Begin
Update
hr.employees
Set employee_id=:new.emp_id,
First_name=substr(:new.name,
instr(:new.name,',')+2),
last_name=
substr(:new.name,1,instr(:new.name,',')-1),
phone_number=:new.phone_number,

email=:new.email
where employee_id=:old.emp_id;
end;
4、
系统事件触发器
系统事件:数据库启动、关闭,服务器错误
create trigger ad_startup
after
startup
on database
begin
-- do some stuff
end;
/

5、 用户事件触发器
用户事件:用户登陆、注销,CREATE / ALTER / DROP / ANALYZE
/ AUDIT / GRANT / REVOKE /
RENAME / TRUNCATE / LOGOFF
例子:记录删除对象
1.
日志表
create table droped_objects(
object_name varchar2(30),

object_type varchar2(30),
dropped_on date);
2.触发器
create or
replace trigger log_drop_trigger
before drop on donny.schema
begin

insert into droped_objects values(
ora_dict_obj_name, -- 与触发器相关的函数

ora_dict_obj_type,
sysdate);
end;
/
3. 测试

create table drop_me(a number);
create view drop_me_view as select *from
drop_me;
drop view drop_me_view;
drop table drop_me;
select *from
droped_objects
禁用和启用触发器
alter trigger <trigger_name> disable;

alter trigger <trigger_name> enable;
事务处理:
在触发器中,不能使用commit /
rollback
因为ddl语句具有隐式的commit,所以也不允许使用
视图:
dba_triggers

本文转自http://www.jb51.net/article/18252.htm

oracle触发器update本表数据的更多相关文章

  1. MySQL触发器更新本表数据异常:Can't update table 'tbl' in stored function/trigger because it

    MySQL触发器更新本表数据异常:Can't update table 'tbl' in stored function/trigger because it 博客分类: 数据库 MySQLJava ...

  2. Oracle通过Navicat导入表数据与机构,数据无法直接查询,需要加双引号的问题

    使用navicat 导入表到ORACLE时,总是会遇到虽然表格完整导入到数据库,但是往往查不出来数据,网上提供的解决办法是把查询的列 加上 双引号,或者表名加上双引号,但这解决办法却减慢了编写sql ...

  3. oracle中字符串与表数据拼接的用法--“||”

    测试过程中,经常需要批量删除或者插入.修改一些表数据或结构,使用手工复制.粘贴其实很麻烦,所以这是我们就可以使用拼接成sql语句的方法来实现操作数据.下面先讲讲oracle中拼接符 || 的用法,如下 ...

  4. MySQL - 问题集 - 触发器更新本表数据异常"Can’t update table ‘tbl’ in stored function/trigger because it is already used by statement which invoked this"

    如果你在触发器里面对刚刚插入的数据进行了 insert/update, 则出现这个问题.因为会造成循环的调用. create trigger test before update on test fo ...

  5. oracle触发器,一个表新增、修改的同时同步另一张表

    oracle创建触发器,把本地新增.修改数据过程同步到另一个服务器上去. 如果是本地,加数据库名即可.如果是远程服务器,不是一台机器,做一个db_link操作即可. ----------------- ...

  6. 关于从Oracle数据库中删除表数据

    1,删除表 drop 1.1 执行drop table table_name  语句 被 drop后的表被放在用户回收站(user_recyclebin)里,而没有被直接删除掉,回收站里的表可以被恢复 ...

  7. C# Oracle.ManagedDataAccess 批量更新表数据

    这是我第一次发表博客.以前经常到博客园查找相关技术和代码,今天在写一段小程序时出现了问题, 但在网上没能找到理想的解决方法.故注册了博客园,想与新手分享(因为本人也不是什么高手). vb.net和C# ...

  8. oracle如何查询哪个表数据量大

  9. oracle 查询之前的表数据

    SELECT * FROM Student  AS OF TIMESTAMP SYSDATE - 3/1440 对SQL的解释说明: SYSDATE :当前时间 1440 :24h*60m=1440m ...

随机推荐

  1. phpstudy添加PHP

    想在phpstudy2018里面增加一个php版本,操作如下: 一.下载php-7.2.19-ts文件,解压缩,放在相应的目录下: 二.修改Apache的配置文件1.修改httpd.conf 配置,D ...

  2. django事务模式

    from django.db import transaction from django.db import transaction with transaction.atomic(): obj = ...

  3. 3.css3文字与字体

    1.css3文字与字体: ①Font-size:大小. ⑴通常使用px.百分比.em来设置大小: ⑵xx-small.x-small.small.medium.large.x-large.xx-lar ...

  4. LabWindows/CVI 下载

    LabWindows/CVI 是National Instruments 公司(美国国家仪器公司,简称NI 公司)推出的交互式C 语言开发平台.LabWindows/CVI 将功能强大.使用灵活的C ...

  5. Linux架构--------Rsync守护进程推和拉

    一.Rsync基本概述 rsync是一款开源.快速.多功能.可实现全量及增量的本地或远程数据同步备份的优秀工具.rsync软件适用于Unix/linux/Windows等多种操作系统平台. 二.Rsy ...

  6. cocos随笔

    随笔:  [ 1 ] active能隐藏元素,且不占空间,但仍存在,索引时,仍能得到 [ 2 ] 碰到参数传不进去的时候可以试着用属性赋值的方法代替传参 [ 3 ] getChildByName是按照 ...

  7. SpringBoot整合MyBatis-Plus代码自动生成类

    在springboot的test测试类下创建 MpGenerator.java   配置  MpGenerator.java public class MpGenerator { @Test publ ...

  8. java:在Conllection接口中实际上也规定了两个可以将集合变成对象数组的操作

    在Conllection接口中实际上也规定了两个可以将集合变成对象数组的操作 //在Conllection接口中实际上也规定了两个可以将集合变成对象数组的操作 List<String> a ...

  9. 【NOIP2016提高A组模拟7.17】寻找

    题目 Bob和Alice出去度蜜月,但Alice不慎走失,Bob在伤心过后,决定前去寻找Alice. 他们度蜜月的地方是一棵树,共有N个节点,Bob会使用下列DFS算法对该树进行遍历. startin ...

  10. 【leetcode】837. New 21 Game

    题目如下: 解题思路:这个题目有点像爬楼梯问题,只不过楼梯问题要求的计算多少种爬的方式,但是本题是计算概率.因为点数超过或者等于K后就不允许再增加新的点数了,因此我们可以确定最终Alice拥有的点数的 ...