Oracle触发器

 触发器:

          最近需求需要写一个触发器,整理下。。我的理解就是数据库表的监听器,,,监听对表的操作来处理一些业务上的问题(比如日志,增删改查数据库等操作。)

触发器语法

语法:
create [or replace] trigger trigger_name
{before | after} trigger_event
on table_name
[for each row]
[when trigger_condition]
trigger_body

其中:

 

trigger_name:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。

before | after : 指定触发器是在触发事件发生之前触发还暗示发生之后触发

trigger_event:触发事件,在DML触发器中主要为insert、update、delete等

table_name:表名,表示发生触发器作用的对象

for each row:指定创建的是行级触发器,若没有该子句则创建的是语句级触发器

when trigger_condition:添加的触发条件

trigger_body:触发体,是标准的PL/SQL语句块

案例

--创建测试表
CREATE TABLE test(
  t_id  NUMBER(4),
  t_name VARCHAR2(20),
  t_age NUMBER(2),
  t_sex CHAR
);
--创建测试表附表
CREATE TABLE ttest(
  tt_id  NUMBER(4),
  tt_name VARCHAR2(20),
  tt_age NUMBER(2),
  tt_sex CHAR
);

创建触发器:插入数据的时候在另外一张表插入,更新也更新处理

CREATE OR REPLACE TRIGGER TEST_TRIGGER
 AFTER DELETE OR INSERT OR UPDATE ON TEST
 FOR EACH ROW
BEGIN
  
  IF INSERTING THEN
    insert into ttest(tt_id,tt_name,tt_age,tt_sex) values(:NEW.t_id,:NEW.t_name,:NEW.t_age,:NEW.t_sex);
    
  ELSIF UPDATING THEN
    IF (:NEW.t_name is not null) THEN
      update ttest set tt_name = :NEW.t_name where tt_id = :NEW.t_id;
    END IF;
  END IF;
END;

AFTER DELETE OR INSERT OR UPDATE ON TEST  监听删除插入更新操作
 FOR EACH ROW  每一行变化都触发

:new  新数据  :old  老数据

测试:

INSERT INTO TEST VALUES(119,'',22,'M');
UPDATE test SET t_age = 33 WHERE t_id = 119;
DELETE test WHERE t_id = 101;

多操作几次。。

这样一个简单的触发器就实现了。。。。其它还有很多业务场景,,但是不排除都是sql的增删改查操作。。。

触发器禁止和启用: 

ALTER TRIGGER trigger_name DISABLE;
ALTER TRIGGER trigger_name ENABLE;

当然也可以手动直接删除触发器。。。。一劳永逸。。。

这里面触发器的编写用到PLSQL语法,补充其它语法使用。。。

--声明方法,定义变量
--赋值操作可以用 := 也可以使用 into 查询语句赋值
declare
    i number(2):=10;        --数值型变量
    s varchar2(10):='小明'; --字符型变量
    ena emp.ename%type;   --引用型变量,直接取出emp表中ename的类型给ena
    emprow emp%rowtype;   --记录型变量,可以理解为可以存一行记录
begin
    dbms_output.put_line(i); --输出语句
    dbms_output.put_line(s);
    select ename into ena from emp where empno=7788;
    dbms_output.put_line(ena);
    select * into emprow from emp where empno=7788;
    dbms_output.put_line(emprow.ename||'的工作为:'||emprow.job);
end;

在PLSQL Developer 控制台查看结果:

--pl/sql中的if判断
--输入小于18的数字,输出未成年
--输入大于18小于40的数字,输出中年人
--输入大于40的数字,输出老年人

declare
--number给个3位表示年龄够了,最大可以是999,输入的写法 & 后根据自己喜欢写个字母
    i number(3):=ⅈ   
begin
    if i<18 then
      dbms_output.put_line('未成年');
      elsif i<40 then
        dbms_output.put_line('中年人');
        else
          dbms_output.put_line('老年人');
          end if;
end;
--pl/sql中的loop循环
--用三种方式输出1到10十个数字
--while循环
declare
   i number(2):=1;
begin
  while i<11 loop
    dbms_output.put_line(i);
    i:=i+1;
  end loop;
end;

--exit循环
declare
  i number(2):=1;
begin
  loop
    exit when i>10;
    dbms_output.put_line(i);
    i:=i+1;
  end loop;
end;

--for循环
declare

begin
  for i in 1..10 loop
     dbms_output.put_line(i);   
  end loop;
end;
--游标:可以存放多个对象,多行记录
--输出emp表中的所有员工的姓名
declare
  cursor c1 is select * from emp;
  emprow emp%rowtype;
begin
  open c1;
       loop
         fetch c1 into emprow;
         exit when c1%notfound;
         dbms_output.put_line(emprow.ename);
       end loop;
  close c1;
end;

空字符串判断

-- Created on 2012-01-04 by KANLIANHUI 
declare 
  -- Local variables here
  i varchar2(16);
begin
  -- Test statements here
  i:='';
  dbms_output.put_line('i的值是:'|| i ||'.');
  if(i='') then 
       dbms_output.put_line('i 是空字符串');
  end if;
   if(i is not null) then 
       dbms_output.put_line('i不为null');       
  end if;
  
   if(i is  null) then 
       dbms_output.put_line('i为null');
  end if;
end;

if嵌套 

if (v_compute_form = 1) then
      current_fee := v_square * price; --本月费用
      if (v_overdue_flag = 1) then
        overdue_fine := previous_fee * 5 / 10000; --滞纳金
      end if;
elsif (v_compute_form = 2) then
      current_fee := record_count * price + v_plan_count1 * extra_price1 + v_plan_count2 * extra_price2 ;
end if;

增删改监听

CREATE OR REPLACE TRIGGER TEST_TRIGGER
 AFTER DELETE OR INSERT OR UPDATE ON TEST
DECLARE
 V_TYPE TEST_LOG.L_TYPE%TYPE;
BEGIN
 IF INSERTING THEN
  --INSERT触发
  V_TYPE := 'INSERT';
  DBMS_OUTPUT.PUT_LINE('记录已经成功插入,并已记录到日志');
 ELSIF UPDATING THEN
  --UPDATE触发
  V_TYPE := 'UPDATE';
  DBMS_OUTPUT.PUT_LINE('记录已经成功更新,并已记录到日志');
 ELSIF DELETING THEN
  --DELETE触发
  V_TYPE := 'DELETE';
  DBMS_OUTPUT.PUT_LINE('记录已经成功删除,并已记录到日志');
 END IF;
 INSERT INTO TEST_LOG
 VALUES
  (USER, V_TYPE, TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); --USER表示当前用户名
END;

判断字符串中是否有某一个字符 

declare aa varchar2 := 'wkressssdfdf';
begin
if instr(aa,'s')>0 then
dbms_output.put_line('有bais字符duzhi');
else
dbms_output.put_line('没有daos字符');
end if;
end;

大概基本上覆盖了很多场景。。。。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值