触发器 trigger

create or replace trigger tr_in
  before insert on doptin  
  
for each row
declare
  v_count number;
  
  
-- local variables here
begin
  select count(
*) into v_count from dopt 
  where doptid 
=:new.proid;
  
  
if v_count =0 then
    insert into dopt(非变异表) values(sq_dopt.nextval,:
new.proid,:new.innum);
  
else
    update dopt set dopt.doptnum 
= doptnum+:new.innum where proid = :new.proid;
  end 
if;
  
--检测是否第一次入库记录,如果第一次入库,则在dopt表中
  
--建立一条记录,否则修改dopt表中库存数量
  exception when others then
    dbms_output.put_line(sqlerrm);
end tr_in;


--------------------


create or replace trigger tr_out
  before insert on doptout  
--触发表
  
for each row
declare
  v_num number;
  
-- local variables here
begin
  select dopt.doptnum into v_num from dopt where dopt.proid 
= :new.proid;
  
if :new.outnum > v_num then
    raise_application_error(
-20001,'库存不足');
  
else
    update dopt set doptnum 
= doptnum - :new.outnum where doptid = :new.proid;
  end 
if;
end tr_out;



---------------------------------------
--1触发事件 insert delete update
--2触发时机
--对dml语句之前还是之后让他工作
--3触发表,触发器为之工作的表
--4触发类型:
-- 4.1行级,语句级触发器即(表级触发器)
create or replace trigger tr_row_after
  after update on emp  
  
for each row
declare
  
-- local variables here
begin
  dbms_output.put_line(
'××行级后触发器工作××');
end tr_row_after; 

-------------------
create or replace trigger tr_row_before
  before update on emp  
  
for each row
declare
  
-- local variables here
begin
  dbms_output.put_line(
'row before trigger test');
end tr_row_before;
----------------------------------------
create or replace trigger tr_tab_before
  before update on emp  
  
declare
  
-- local variables here
begin
  dbms_output.put_line(
'table  grade before working');
end tr_tab_before;
-------------------------
create or replace trigger tr_tab_after
  before update on emp  
  
declare
  
-- local variables here
begin
  dbms_output.put_line(
'table  grade after working');
end tr_tab_after;
------------------------------------------执行结果:
table  grade after working
table  grade before working
row before trigger test
row after trigger test
row before trigger test
row after trigger test
row before trigger test
row after trigger test
----------------------
-----------触发操作(触发器中语句块
---周末不能对员工表做操作

create or replace trigger tr_emp2_in_up_de
  before insert or update or delete on emp2  
  
declare
  v_day varchar2(
20);
  
-- local variables here
begin
  select to_char(sysdate,
'dy') into v_day from dual;

    
if inserting then
        raise_application_error(
-20001,'have the rest day can not control employ');
    elseif updating then
        raise_application_error(
-20001,'have the rest day not control employ');
    elseif deleting then
        raise_application_error(
-20001,'have the rest day cnot control employ');
    end 
if;

end tr_emp2_in_up_de;
---------触发器执行
--ml操作请求---》触发器工作---》dml操作结束----》commit or roback
--触发器不能还有事务控制语句;commit roback
---不能含有ddl语句,因为ddl语句会自动提交;
---触发器代码大小不能超过512k,可以使用触发器调用过程或者函数调用,解决较大代码调用问题
---注意,触发器都是在dml结束前执行 ,delete中 :old指删除的要操作de旧记录,insert中:new指要插入的新记录
--after,与 before触发器的区别,update即可以:new,又可以:old,他们只能在行集触发器中使用..
--行级before触发器可以修改:new的值,而行级后after触发器则不行
--1触发时机,before比after先执行,
--2-定义取编号触发器
create or replace trigger tr_teb_before
  before insert on teb  
  
for each row
declare
  
-- local variables here
  v_num number;
begin
   select sq_teb.nextval into v_num from dual;
   :
new.tebid := v_num;
end tr_teb_before;
---instead of 触发器 视图触发器 做修改操作,视图只是用来查询的,一旦用修改则用instead of触发器
---多表复杂视图 不能通过dml操作修改,
--和普通dml触发器的区别:instead of 操作会中断dml操作
--普通触发器是dml操作事务的一部分
--instead of触发器会结束当前dml操作
--dml操作请求(即dml操作结束)---》instead of触发器工作, set serveroutput on;insert into v_teb2 values(1,'a');
create or replace trigger tr_teb2
  instead of insert on v_teb2  
  
for each row
declare
  
-- local variables here
begin
  dbms_output.put_line(
'instead of trigger working');
  insert into teb2 values(sq_teb.nextval,
'trigger working');
end tr_teb2;

----约束表,触发表,触发器工作的表,example:部门表就是员工表的约束表
----变异表,就是dml操作过程的触发表
----旧数据--脏数据--》新数据
---long double 8b  1101 0100 -----1021 2121----->1200 1323
----DML开始操作--》行级触发器工作---》end结束操作。
----每个部门最多6人,6人后,不允许往这个部门添加员工,和修改其他部门为这个部门员工
----行级触发器不能读取变异表,
---触发表:对于触发器而言,就是触发器为之定义的表
----变异表:就是当前dml操作所影响的表(经常来说触发表就是变异表)
create or replace trigger tri_emp
  before insert or update on emp3   
  
for each row
declare
  
-- local variables hereer
  v_count number;
begin
  select count(
*) into v_count from emp3(本表:(即变异表行级触发器不允许读取)) where emp3.deptno = :new.deptno;
  
if v_count >= 6 then
    raise_application_error(
-20001,'every dept can not over 6 peaple');
  end 
if;
end tri;

---矛盾;行级触发器不允许查询变异表,而表级触发器不允许使用:new
----解决方案:
--1,建立包,定义一个共同变量,用来存放部门编号变量
create or replace 
package pak_deptno is
  v_deptno number;
end pak_deptno;
--2,建立一个行级前或者后触发器,仅仅将操作行的部门编号放入包中。
create or replace trigger tri_row_emp3
  after insert or update on emp3   
  
for each row
declare
 
begin
  pak_deptno.v_deptno:
=:new.deptno;
end tri_row_emp3;
--3,建立一个表级后触发器中查询变异表,来确定是否可以添加.
create or replace trigger tri_table_emp
  after insert or update on emp3   
declare
  
-- local variables hereer
  v_count number;
begin
  select count(
*) into v_count from emp3 where emp3.deptno = pak_deptno.v_deptno;
  
if v_count >= 6 then
    raise_application_error(
-20001,'every dept can not over 6 peaple');
  end 
if;
end tri_table_emp;


----如果是一条insert语句,仅仅插入一行记录,则oracle中行级触发器允许查询变异表..
---insert into emp3 select * from emp where deptno=10;

posted on 2012-06-03 23:06 youngturk 阅读(279) 评论(0)  编辑  收藏 所属分类: Oracle


只有注册用户登录后才能发表评论。


网站导航:
 
<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

公告

this year :
1 jQuery
2 freemarker
3 框架结构
4 口语英语

常用链接

留言簿(6)

随笔分类

随笔档案

文章分类

文章档案

相册

EJB学习

Flex学习

learn English

oracle

spring MVC web service

SQL

Struts

生活保健

解析文件

搜索

最新评论

阅读排行榜

评论排行榜