【oracle资料整理】--【16】触发器

 触发器
    <1>加强约束条件
    <2>实现关联操作  在一个表中修改数据 导致另一个表数据的修改
  

--ORACLE中的 触发器
 用途 :加强约束 条件 的
 --希望在表中插入的数据的日期大于系统时间
   Create table test(
   xh number(2) primary key,
   hdate date check (hdate > sysdate)
);
数据库无法建立的

   Create table test(
   xh number(2) primary key,
   hdate date check (hdate > to_date('20050501','yyyymmdd'))
);
这个可以建

建立触发器的语法
  create or replace trigger <触发器名>
  after/before insert/update/delete on <表名>
  for each row
  begin

  exception

  end;

--触发器中的PL/SQL块(DML / tcl)可以写什么样的SQL语句呢
      DML语句 别的都不能写(COMMIT/rollback都不能写)


after/before 以后/以前 
insert/update/delete 触发的SQL语句
for each row 行级 - 语句级

--sql语句和触发器的Pl/SQL形成一个整体的事务

 

--当表emp中加入员工的时候,如果这个员工的部门
在部门表中没有,则在部门表中dept插入该部门信息,
要求部门编号一定要大于77

--可以使用when的选项来改善触发器的效率

create or replace trigger emptr
before insert on emp   --insert语句触发
for each row          --行级触发器
when (new.deptno >77 and new.ename='JOHN')  --条件 (满足条件才触发)
declare
  n_count number;
begin
  --先检查加入的员工的部门是否存在
  --:new代表新插入到EMP中的那条记录 EMP%rowtype
  --if :new.deptno > 77 then
   select count(*) into n_count
   from dept where deptno = :new.deptno;
 
  --如果不存在就在部门表中加入该部门
  if n_count = 0 then
    insert into dept values (:new.deptno,
     '人事','北京');
  end if;      

-- end if;

end;

--触发语句
insert into emp(empno,ename,deptno) values
 (9000,'mike',50);


--for each row
--日志表
 create table log(
   id number ,
   ndate date
);

--触发器
create or replace trigger emptr2
after update on emp
for each row
begin
--update
--改后的值 :new.empno :new.ename
--改前的值 :old.empno :old.ename
--insert
--只有:new
--delete
--只有:old
  insert into log values (:new.empno,sysdate);
end;

--修改1条记录,触发器触发几次??(1次)
update emp set sal=2000 where empno=7369;


--改14条记录 ,触发器工作几次??(14次)
update emp set sal=1000 ;  14次


--语句级
create or replace trigger emptr2
after update on emp
begin
  insert into log values (222,sysdate);
end;


--一句话,改14条记录 ,触发器工作几次????1次
update emp set sal=1000;

--行级 根据sql语句的影响记录的行数来决定触发的次数
--语句级  根据sql语句的个数来决定触发的次数
-- 使用最多的是行级触发器

 

--什么语句触发的触发器 可以用
--inserting(boolean值)  insert语句
--updating(boolean值)   update语句
--deleting(boolean值)   delete语句

--使用触发器的时候容易犯的错误
--变异表
--不能够在触发器对触发表做select操作
create or replace trigger em1
after delete on emp
for each row
declare
 n number;
begin
  select count(*) into n from emp;
end;

 

 


--如何防止错误删除???
delete from dept;

--触发器
  create or replace trigger tr_del
  before delete on dept
  for each row
  begin
 --内部引起异常
    raise_application_error(-20001,'不能删除');
  end;  

  alter trigger tr_del disable; --使触发器不工作
  alter trigger tr_del enable; --使触发器工作

--希望在表中插入的数据的日期大于系统时间
create or replace trigger tr_test
after insert or update of hdate
or delete on test
for each row
begin
  if inserting then --insert语句触发
  dbms_output.put_line('insert');
  --插入的每一行用:new表示(test%rowtype)
  if :new.hdate <= sysdate  then
  --不能进行数据插入
   raise_application_error(-20001,'日期小于系统时间');
  end if;
 
  elsif updating then --update语句触发
  dbms_output.put_line('update');
  if :new.hdate <= sysdate  then
  --不能进行数据插入
   raise_application_error(-20001,'日期小于系统时间');
  end if;
   
 
  elsif deleting then --delete语句触发
  dbms_output.put_line('delete');
 
  end if;
 
exception
 when others then
   raise_application_error(-20002,'日期小于系统时间');
end;

--希望在表中插入的数据的日期大于系统时间
   Create table test(
   xh number(2) primary key,
   hdate date );

 create or replace trigger tr_test
 after insert on test
 for each row
 begin
  if :new.hdate <= sysdate then
    raise_application_error(-20001,'小于系统时间');
  end if;

 end;

insert into test values (1,to_date('20050401','yyyymmdd'));

insert into test values (1,sysdate+1);

--ORACLE中的内置程序包
  DBMS_JOB  自动作业调度
    能不能写一个存储过程 每隔一定时间自动运行(定时器)
   dbms_job.submit()   提交作业到系统 指定它什么时候运行
  
--DBMS_JOB 作业调度包(指定PL/SQL过程定时自动执行)
--初始化参数init.ora
 job_queue_processes = 1 --作业队列进程的个数(最大36个)
 job_queue_interval = 60 --进程每隔多少时间扫描作业队列(60s)

 processes=150  --并发用户的数量
 open_cursors =300 --存储过程中使用游标的数量

 
--DBMS_JOB包中的方法
 procedure submit(job out binary_integer,
   what in varchar2,
   next_date in date default sysdate,
   interval in varchar2 default null,
   no_parse in boolean default false);

 procedure change(job in binary_integer,
   what in varchar2,
   next_date in date,
   interval in varchar2);

 procedure what(job in binary_integer,
    what in varchar2);

 procedure next_date(job in binary_integer,
    next_date in date);
 
 procedure interval(job in binary_integer,
   interval in varchar2);

--实际例子
 create  sequence temp_seq
  start with 1;

 create table temp_table(
       num_col number,
       char_col varchar2(50));


 create or replace procedure tempinsert is
 begin
   insert into temp_table(num_col,char_col)
   values (temp_seq.nextval,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
  
   commit;
 end;

--注册每10秒运行一次
 declare
   v_job number;
 begin
  dbms_job.submit(v_job,'tempinsert();',sysdate,'sysdate + (10 / (24 * 60 * 60))');
  commit;
 end;

 
--删除作业
 dbms_job.remove(job in binary_integer);

--查看作业信息
 select * from user_jobs;
 select * from dba_jobs;

 内置程序包 大约有25个 都是sys拥有

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值