功能:
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. SQLSERVER 备份恢复之后提示缺少创建表权限的问题解决

    1. 同事这边出现异常: 执行功能是报错, 这个错误 应该是创建临时表时没有权限触发的. 方法应该很简单 缺少权限增加权限即可 2. 这里需要使用sa 或者是 具有sa权限的用户登录 打开 数据库级别 ...

  2. java基础笔记(10)

    Html:载体      CSS:样式   JavaScript:特效 html: 1. <html></html>称为根标签,所有的网页标签都在<html>< ...

  3. 【暑假培训1】test1

    T1: 30pts:直接暴力三层循环枚举 就就就先不写代码了qwq: 70pts: 因为X+Y+Z==0 所以我们可以考虑枚举X和Y,然后利用↑式子求出Z=-X-Y: 然后touli xcg的70pt ...

  4. TScreen研究(有待研究)

    先扔在这里,待研究: http://blog.csdn.net/lailai186/article/details/8141170 procedure TForm1.Button1Click(Send ...

  5. P4556 [Vani有约会]雨天的尾巴(线段树合并+lca)

    P4556 [Vani有约会]雨天的尾巴 每个操作拆成4个进行树上差分,动态开点线段树维护每个点的操作. 离线处理完向上合并就好了 luogu倍增lca被卡了5分.....于是用rmq维护.... 常 ...

  6. Spark Streaming整合logstash + Kafka wordCount

    1.安装logstash,直接解压即可 测试logstash是否可以正常运行 bin/logstash -e 'input { stdin { } } output { stdout {codec = ...

  7. java字符流读取文件

    package ba; import java.io.*; public class zifuTest { public static void main(String[] args) { FileI ...

  8. HTML-图片和多媒体

    1.图片和多媒体 (1)    图片:img元素 src 属性:图片路径: alt 属性:图片无法显示时使用的替代文字: title:鼠标悬停时显示的文字 : <img src="图片 ...

  9. 【React 7/100 】 虚拟DOM和Diff算法

    虚拟DOM和Diff算法 React更新视图的思想是:只要state变化就重新渲染视图 特点:思路非常清晰 问题:组件中只有一个DOM元素需要更新时,也得把整个组件的内容重新渲染吗? 不是这样的 理想 ...

  10. console 对象

    JavaScript 原生中默认是没有 Console 对象,这是宿主对象(也就是游览器)提供的内置对象. 用于访问调试控制台,在不同的浏览器里效果可能不同.Console 对象方法: