当前位置: 代码网 > it编程>数据库>Oracle > Oracle使用insert触发器遇到的问题及解决

Oracle使用insert触发器遇到的问题及解决

2024年10月15日 Oracle 我要评论
oracle使用insert触发器遇到的问题首先trigger基本语句create or replace trigger 'trigger_name'--触发器名称before insert --或

oracle使用insert触发器遇到的问题

首先trigger基本语句

create or replace trigger 'trigger_name'--触发器名称
before insert --或 after insert (触发时机)
--关键字before和after用于标识触发时间,顾名思义,before代表触发器里面的命令在dml修改数据之前执行,
--after代表触发器里面的命令在dml修改数据之后执行。
referencing new as new --或old as old (用于触发器中参数使用)
--注:before中的new指的是当前插入的集,after中的old指的是当前插入的集
for each row --指当前触发器为行级触发器(行级触发器相对于语句级触发器)
--行级触发器能够通过 :new.属性 和 :old.属性等获得update或者insert发生之前的新值和发生值之后的旧值。
declare --声明变量……
begin
end;

关于行级触发器的 :new.属性 和 :old.属性使用

trigger tongbujiayi_sfzh
before
 delete or update of d_sfzh
 on t_da_jkda_rkxzl
referencing new as new old as old
 for each row
begin
 if updating
 then
insert into t_da_jkda_rkxzl_gwandjy(id,d_grdabh,p_rgid,d_sfzh,d_sfzhxgq,d_datzxgh,d_xm,d_bgsj,d_bgzt)
values (sys_guid(),:old.d_grdabh,:old.p_rgid,:old.d_sfzh,:new.d_sfzh,'',:old.d_xm,sysdate,'2');
elsif deleting
 then
insert into t_da_jkda_rkxzl_gwandjy(id,d_grdabh,p_rgid,d_sfzh,d_sfzhxgq,d_datzxgh,d_xm,d_bgsj,d_bgzt)
values (sys_guid(),:old.d_grdabh,:old.p_rgid,:old.d_sfzh,'','',:old.d_xm,sysdate,'1');
end if;
end;

在oracle中执行dml语句的时候是需要显示进行提交操作的。

当我们进行插入的时候,会触发触发器执行对触发器作用表和扩展表的种种操作,

但是这个时候触发器和插入语句是在同一个事务管理中的,因此在插入语句没有被提交的情况下,我们无法对触发器作用表进行其他额外的操作。

如果执行其他额外的操作则会抛出如下异常信息。

ora-04091:表*****发生了变化触发器/函数不能读它

此次触发器产生场景:

一个身份证号及个人信息导入到系统中,在系统中修改了关于疫情的信息。

但再次导入此人的信息时(每次导入的信息都不包含关于疫情的信息),则需要同步。

由此引入触发器,触发条件为insert

trigger detection_users_syn_vaccine
  before insert on detection_users
  referencing new as new
  for each row

declare --oracle中声明多个属性时只需要用一次declare即可
  v_id              detection_users.id%type;--此处声明的属性是按照detection_users表中的属性声明
  v_is_vaccination  detection_users.is_vaccination%type;
  v_vaccine1        detection_users.vaccine1%type;
  v_vaccine2        detection_users.vaccine2%type;
  v_vaccine3        detection_users.vaccine3%type;
  v_num_vaccination detection_users.num_vaccination%type;
  --声明游标查询此人添加之前的接种信息
  cursor latests is
    select id,
           is_vaccination,
           vaccine1,
           vaccine2,
           vaccine3,
           num_vaccination
      from (select t.*, row_number() over(order by nvl(zdrq, '0') desc) rn
              from (select *
                      from (select id,
                                   is_vaccination,
                                   vaccine1,
                                   vaccine2,
                                   vaccine3,
                                   num_vaccination,
                                   (case
                                     when (vaccine3 is not null) then
                                      vaccine3
                                     when (vaccine2 is not null) then
                                      vaccine2
                                     when (vaccine1 is not null) then
                                      vaccine1
                                     else
                                      ''
                                   end) as zdrq
                              from detection_users
                             where "identity" = :new."identity"
                               and is_vaccination is not null)) t)
     where rn = 1;
begin

  open latests;
  fetch latests
    into v_id,
         v_is_vaccination,
         v_vaccine1,
         v_vaccine2,
         v_vaccine3,
         v_num_vaccination;
         ---打印语句
--  dbms_output.put_line('latests===' || v_id || '**' || v_is_vaccination || '**' ||
--                       v_vaccine1 || '**' || v_vaccine2 || '**' ||
--                       v_vaccine3 || '**' || v_num_vaccination);
--  dbms_output.put_line('new===' || :new.id || '**' || :new.is_vaccination || '**' ||
--                       :new.vaccine1 || '**' || :new.vaccine2 || '**' ||
--                       :new.vaccine3 || '**' || :new.num_vaccination);

  if inserting then
    :new.is_vaccination  := v_is_vaccination;--将打开的cursor赋值到新插入的这列数值中
    :new.vaccine1        := v_vaccine1;
    :new.vaccine2        := v_vaccine2;
    :new.vaccine3        := v_vaccine3;
    :new.num_vaccination := v_num_vaccination;
  
  end if;
  --fetch next from from_inserted intov_id,v_is_vaccination,v_vaccine1,v_vaccine2, v_vaccine3,v_num_vaccination;
  --循环,此处cursor只有一条,不需要。
  close latests;

end;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com