日期:2014-05-16  浏览次数:20620 次

触发器实例

?

create or replace trigger updEmp_trig
  before update on emp  
  for each row
declare
  -- local variables here
begin

  dbms_output.put_line('触发器被触发了...');
  --设计要求,将更新以后的工资插入一张新表emp2中,
  --这个新表的结构与EMP表中雇员的基本信息一致
  insert into emp2(empno,ename,sal) values(:old.empno,:old.ename,:new.sal);
  dbms_output.put_line(:old.empno||' 号雇员,姓名为:'||:old.ename||' , 他的工资由 '||:old.sal||' 变化到了 '||:new.sal);
end updEmp_trig;

--只能够通过前触发器完成此项任务,不可以是后触发器
create or replace trigger employees_ins_trigger
  before insert or update on employees  
  referencing old as old_value new as new_value
  for each row
  --只有不等于80部门的数据才导致触发器工作
    when (new_value.department_id<>80) 
declare
  -- local variables here
begin
 
  --只有80部门的雇员能够获得COMMISSION_PCT的值,其它部门的值设为0
    --将commission_pct的值设置为0
     :new_value.commission_pct:=0;
  
end employees_ins_trigger;

--假设使用后触发器会怎么样?
--触发器编译报错。因为按照业务逻辑,为了实现这个业务,必须使用前触发器。

--只能够通过前触发器完成此项任务,不可以是后触发器
create or replace trigger employees_ins_trigger
  after insert or update on employees  
  referencing old as old_value new as new_value
  for each row
  --只有不等于80部门的数据才导致触发器工作
    when (new_value.department_id<>80) 
declare
  -- local variables here
begin
 
  --只有80部门的雇员能够获得COMMISSION_PCT的值,其它部门的值设为0
    --将commission_pct的值设置为0
     :new_value.commission_pct:=0;
  
end employees_ins_trigger;

 

--只有在工作时间才能够对HR用户的EMPLOYEES表和DEPARTMENTS表做DML操作
--工作时间定义为 8:00AM——17:00PM


create or replace trigger emplyoees_limits_trig
  before insert or update or delete on employees  
  for each row
declare
  -- local variables here
  v_timestr varchar2(30);
begin

 --只有在工作时间才能够对HR用户的EMPLOYEES表和DEPARTMENTS表做DML操作
 --工作时间定义为 8:00AM——17:00PM
 
 --对系统时间作出分析,如果对操作时间进行分解以后,判断小时数小于8:00
 --或者小时数大于17:00,则引发错误。
  
 select to_char(sysdate,'yyyy-mm-dd:hh24:mi:ss') into v_timestr from dual;
  
  if(小时数<8 or 小时数>17) then
    raise_application_error(-20001,'非工作时间,不能进行DML操作');
  end if;
  
  
end emplyoees_limits_trig;

 

--认识行级触发器与语句级触发器的区别

create or replace trigger updEmp_stmt_trig
  before update on emp  
declare
  -- local variables here
begin
  dbms_output.put_line('语句级触发器被触发了...');
end updEmp_trig;


create or replace trigger updEmp_trig
  before update on emp  
  for each row
declare
  -- local variables here
begin

  dbms_output.put_line('触发器被触发了...');
  --设计要求,将更新以后的工资插入一张新表emp2中,
  --这个新表的结构与EMP表中雇员的基本信息一致
  insert into emp2(empno,ename,sal) values(:old.empno,:old.ename,:new.sal);
  dbms_output.put_line(:old.empno||' 号雇员,姓名为:'||:old.ename||' , 他的工资由 '||:old.sal||' 变化到了 '||:new.sal);
end updEmp_trig;


--自动派生值

--当我们向一张数据表中插入数据时,希望id这个列的值能够自动增长(初始值为1000),
--每次增加1

create table testtab(

   newsid  number not null,
   newstitle varchar2(50),
   newstype  varchar2(30)
   );
   
insert into testtab values(999,'意大利与新西兰1:1战平','世界杯新闻');

select * from testtab;

insert into testtab values(88,'西安地区最近持续高温','社会新闻');


--为了解决这个问题,需要两个数据库对象,并且他们还需要关联以后才能够解决
--第一个对象是序列或者序号

create sequence testtab_seq
minvalue 1000
maxvalue 999999
start with 1000
increment by 1;

--testing

insert into testtab values(testtab_seq.nextval,'意大利与新西兰1:1战平','世界杯新闻');

insert into testtab values(testtab_seq.nextval,'西安地区最近持续高温','社会新闻');

insert into testtab values(66,'西安地区最近持续高温','社会新闻');


insert into testtab values(4500,'西安地区最近持续高温','社会新闻');


select * from testtab;

--第二步需要将序号和触发器关联

commit;

 

 


--只能够通过前触发器完成此项任务,不可以是后触发器
create or replace trigger employees_ins_trigger
  before insert or update on employees  
  referencing old as old_value new as new_value
  for each row
  --只有不等于80部门的数据才导致触发器工作
    when (new_value.department_id<>80) 
declare
  -- local variables here
begin
 
  --只有80部门的雇员能够获得COMMISSION_PCT的值,其它部门的值设为0
    --将commission_pct的值设置为0
     :new_value.commission_pct:=0;
  
end employees_ins_trigger;

 

create or replace trigger testtab_trig
  before insert on testtab  
  for each row
declare
  -- local variables here
begin
  --当插入数据之前,从序号中派生值赋给insert语句中的newsid
  --这样就保证了newsid中的值一定是从序号中获取的