触发器的使用细节(pgsql与oracle)

       触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到(引用于百度百科------触发器(数据库原理术语)_百度百科)。

       个人理解:即对数据库中主要表格数据变化的未雨绸缪(BEFORE)与亡羊补牢(AFTER)。例子中 oracle 以 PLSQL 为例,pgsql以 NAVICATE 为例。

-------------------------------------------oracle------------------------------------------------------------------------------

Create Or Replace Trigger 触发器名字 --([Tri_表名]作为触发器的名字 -> 单纯的容易看出来是对哪个表的触发器 )
  After Delete Or Insert Or Update On 表名 --(表名 -> 主要表格,[After]关键字 -> 亡羊补牢)
  For Each Row --(一般都是row行,其他的还没用到)

Declare
--用到的变量 
  v_id Number(24);
  v_Type    varchar2(10);
  v_Cnt     Number(10);
--  ...... 
  
Begin
  If Inserting Then
    v_Type := 'insert';   ---运行步骤,当异常后容易找错误程序位置
    v_Prim := :New.Id;    --- :New.Id  -> 插入数据的id值
    
    Insert Into 表名bak   -- 表名bak:一般是其他库的表或者该库的备用表
      (Id,
       Name,
       ...
       )
    Values
      (:New.Id,
       :New.Name,
       ...
       );
    Commit;  --做数据增改查,但不确定是否用提交事务,那么就写commit,错了再删!存过、函数亦如此。
    If v_Prim = 123456 Then   --存在特殊处理的数据,单独处理
      For Cur In (Select Id From xxx ) Loop   --这里的游标,只是用来演示,根据情况使用
        Begin
                 
          If v_xx = 0 Then
            ...       
          End If;
          
        Exception
          When Others Then
            Null;
        End;
      End Loop;
      
    End If;
    
 END;  ---结束insert的触发,这里也可以不用end,那么下面的 update 钱的 if 可以改成 Elsif,用 end 方便可读性(菜鸟认为,if 对应 end 越近越容易读)。
    
  if Updating Then
    v_Type := 'update';
    v_Prim := :Old.Id;  ---更改的数据行的id值
    
    Update 表名bak
       Set Name               = :New.Name         
     Where Id = v_Prim;
    Commit;
  
  
  
  Elsif Deleting Then
    v_Type := 'delete';
    v_Prim := :Old.Id;
  
    Delete From 表名bak Where Id = v_Prim;
     
     Commit;
Exception
  When Others Then
    v_Err_Msg := Substr(Sqlerrm, 1, 1000);
    Insert Into  Run_tri_Err                  ------对异常做个记录买房变查询
      (Table_Name, Primval, Type, Errmsg, Errtime)
    Values
      (表名, v_Prim, v_Type, v_Err_Msg, Sysdate);
    Commit;
End;

----------------------------------------------------pgsql-------------------------------------------------------------------

pgsql中需要定义一个触发器函数,然后在配置对应表调用的触发器函数(变成了两步,oracle一步)。

CREATE OR REPLACE FUNCTION "scheme名字"."触发器名字"() --scheme名字   触发器名字
  RETURNS "pg_catalog"."trigger" AS $BODY$             ---这里是固定的
	
Declare
  v_Prim       numeric(24);
  v_Err_Msg    varchar(1000);
  v_Type       Char(1);
  v_Cnt        numeric(10);

  v_cur cursor for                                 -- 定义游标是在这里
	Select Id   From xxx;
	 
BEGIN
 IF (TG_OP = 'INSERT')  then 
  v_Type := 'I';
  v_Prim := New.Id;    --这里的NEW前面没有 : 
	
    Insert Into 表名bak  --同oracle
      (Id,
       Name,
       ...)
    Values
      (New.Id,
       New.Name,
       ...
       );
      
      if New.Id = 12345  then
          For Cur In v_cur Loop         ---游标的使用
          ...
          end loop;
      
      
     end if;          
  	RETURN NEW;	---返回处理完的数据,很关键,否则报错
  END IF;

  IF (TG_OP = 'UPDATE')  then  
   v_Type := 'U';
     v_Prim := Old.Id;
 
     Update 表名bak
        Set Name               = New.Name,
            ...
      Where Id = v_Prim;
      RETURN NEW;	
  END IF; 
     
  IF (TG_OP = 'DELETE')  then  
     v_Type := 'D';
     v_Prim := Old.Id;
   
     Delete From zhejiang_g5.Cm_Link Where Id = v_Prim;
     RETURN NEW;	
  END IF;   


Exception
  When Others Then
    v_Err_Msg := Substr('error', 1, 1000);
    Insert Into Run_tri_Err
      (Table_Name, Primval, Type, Errmsg, Errtime)
    Values
      ('表名', v_Prim, v_Type, v_Err_Msg, current_date);
END;
		
$BODY$                                   ---这里是固定的
  LANGUAGE plpgsql VOLATILE              ---这里是固定的
  COST 100                               ---这里是固定的

查询表->设计表 -> 定义触发器(这样设置容易测试,同样也可以在触发器中直接添加)

 剩下的就是测试通过了,触发器测试很费劲,愿君耐心!!不要像我一样抓狂~~哈哈哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值