一个Oracle触发器的例子

有一个表,表名是xx,有ABCD四个字段,正常情况下,ABC、ABD这三个字段都可以唯一确定一条记录,按理应该做成唯一索引,但由于历史原因,该表存在重复数据,但要删掉哪一条需要人工判断,无法用语句批量删除,于是唯一索引加不上。但为了保证以后数据的准确性,需要控制新插进去的记录是唯一的。于是我写了一个触发器,当新插进去的记录与现有记录重复时就报错:

 

CREATE global temporary TABLE g_xx_temp
 (flatdocid     int,
  modeldocid     int,flatdocrev int,modeldocrev int) ON COMMIT DELETE ROWS;


CREATE OR REPLACE TRIGGER trg_xx_row
  before INSERT or update
  ON xx
  FOR EACH ROW
  DECLARE
    -- local variables here
  BEGIN
    insert into g_xx_temp(flatdocid,modeldocid,flatdocrev,modeldocrev)
      values(:NEW.flatdocid,:NEW.modeldocid,:NEW.flatdocrev,:NEW.modeldocrev);
  END;


CREATE OR REPLACE TRIGGER trg_xx
  after INSERT or update
  ON xx
  --FOR EACH ROW
  DECLARE
    -- local variables here
    v_count int;
    v_flatdocid int;
    v_modeldocid int;
    v_flatdocrev int;
    v_modeldocrev int;
    CURSOR c_temp IS SELECT flatdocid,modeldocid,flatdocrev,modeldocrev from g_xx_temp;
  BEGIN

    OPEN c_temp; 
    LOOP 
      FETCH c_temp INTO v_flatdocid,v_modeldocid,v_flatdocrev,v_modeldocrev;
      select count(1) into v_count from xx
        where flatdocid=v_flatdocid and modeldocid=v_modeldocid and flatdocrev=v_flatdocrev;
      if (v_count>=2) then
         RAISE_APPLICATION_ERROR(-20001, '非法数据1:flatdocid='||to_char(v_flatdocid)||',modeldocid='||to_char(v_modeldocid)||',flatdocrev='||to_char(v_flatdocrev));
      end if;
     
      select count(1) into v_count from xx
        where flatdocid=v_flatdocid and modeldocid=v_modeldocid and modeldocrev=v_modeldocrev;
      if (v_count>=2) then
         RAISE_APPLICATION_ERROR(-20001, '非法数据1:flatdocid='||to_char(v_flatdocid)||',modeldocid='||to_char(v_modeldocid)||',modeldocrev='||to_char(v_modeldocrev));
      end if;
     
      EXIT WHEN c_temp%NOTFOUND;
    end loop;
   
    CLOSE  c_temp;
    
  END;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle 数据库中,触发器的语法格式为: ``` CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name [FOR EACH ROW] [ENABLE/DISABLE] [WHEN condition] BEGIN -- 触发器操作,可以使用 PL/SQL 语言编写 END; ``` 其中,`OR REPLACE` 关键字表示如果同名的触发器已经存在,则替换它;`BEFORE` 或 `AFTER` 关键字用于指定触发器是在执行 DML 操作前还是后触发;`INSERT`、`UPDATE` 或 `DELETE` 关键字用于指定触发器是在哪种 DML 操作时触发;`table_name` 是要对其触发器进行定义的表名;`FOR EACH ROW` 关键字表示这是一个行级触发器,每次 DML 操作都会对每一行数据都触发一次;`ENABLE/DISABLE` 关键字表示触发器是否启用;`WHEN condition` 关键字表示触发器执行的条件,可选项。 以下是一个简单的 Oracle 触发器示例,当在 `employees` 表中插入一条记录时,会自动向 `logs` 表中插入一条日志记录: ``` CREATE OR REPLACE TRIGGER insert_employee_log AFTER INSERT ON employees FOR EACH ROW BEGIN INSERT INTO logs (log_time, log_message) VALUES (SYSDATE, 'A new employee was inserted.'); END; ``` 在这个例子中,触发器的名称是 `insert_employee_log`,触发时间是 `AFTER INSERT`,操作的表名是 `employees`,触发器主体使用 `INSERT INTO` 语句向 `logs` 表中插入了一条日志记录。`SYSDATE` 是一个系统函数,用于获取当前日期和时间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值