在主表上的数据库触发器中将数据插入临时表

Posted

技术标签:

【中文标题】在主表上的数据库触发器中将数据插入临时表【英文标题】:Insert data into staging table in databse trigger on main table 【发布时间】:2017-08-18 18:52:51 【问题描述】:

我有以下要求-

我有 2 个表 Main Table A ,Staging table B

我在主表 A 上编写了一个插入前触发器来检查一些错误数据。如果数据错误,则将其插入临时表B,以便用户查看错误并进行更正,然后再次上传数据。 我的问题是 - 在插入语句之后使用 raise_form_trigger_failure 时,数据没有插入到临时表中。还有其他方法吗?

触发代码-

create or replace trigger CCM_TEST 
   before insert OR UPDATE ON "CCM_MANAGER" 
   for each row 
    declare
  l_user varchar2(500);
  v_user number;
  v_cost_centre number;
  v_company_code number;
  v_show_error varchar2(100);
begin  
l_user := NVL(v('APP_USER'), user);
   if inserting then 

           begin 
            select count(1)
            into v_cost_centre
            From gl_code_combinations
            where segment2=:new.cost_center
            and enabled_flag ='Y';

            if (v_cost_centre= 0) then    
             v_show_error:='Cost Centre does not exists!!  '||'Cost Centre -'||:new.cost_center;      
             :new.CHECK_INSERT_FLAG:='Y';

              Insert into CCM_MANAGER_STG(COMPANY_CODE,
              COST_CENTER,
              USER_NAME,
              EFFECTIVE_START_DATE,
              EFFECTIVE_END_DATE,
              CREATED_BY,
              CREATION_DATE,
              LAST_UPDATED_BY,
              LAST_UPDATE_DATE,
              LINE_ID,
              CHECK_INSERT_FLAG,
              SHOW_ERRORS) values
              ( :new.COMPANY_CODE,
              :new.COST_CENTER,
              :new.USER_NAME,
              :new.EFFECTIVE_START_DATE,
              :new.EFFECTIVE_END_DATE,
              :new.CREATED_BY,
              :new.CREATION_DATE,
              :new.LAST_UPDATED_BY,
              :new.LAST_UPDATE_DATE,
              :new.LINE_ID,
              :new.CHECK_INSERT_FLAG,
              v_show_error);
              end if;
            raise_application_error (-20001, 'Cost Centre does not exists!!  '||'Cost Centre -'||:new.cost_center||' ');                              
          exception
            when others then
            --raise_application_error (-20001, sqlerrm);
            null;

      end;

       begin 
            select count(1)
            into v_company_code
            From gl_code_combinations
            where segment1=:new.company_code
            and enabled_flag ='Y';

            if (v_company_code= 0) then   

             v_show_error:='Company Code does not exists!!'; 
             :new.CHECK_INSERT_FLAG:='Y';

              Insert into CCM_MANAGER_STG(COMPANY_CODE,
              COST_CENTER,
              USER_NAME,
              EFFECTIVE_START_DATE,
              EFFECTIVE_END_DATE,
              CREATED_BY,
              CREATION_DATE,
              LAST_UPDATED_BY,
              LAST_UPDATE_DATE,
              LINE_ID,
              CHECK_INSERT_FLAG,
              SHOW_ERRORS) values
              ( :new.COMPANY_CODE,
              :new.COST_CENTER,
              :new.USER_NAME,
              :new.EFFECTIVE_START_DATE,
              :new.EFFECTIVE_END_DATE,
              :new.CREATED_BY,
              :new.CREATION_DATE,
              :new.LAST_UPDATED_BY,
              :new.LAST_UPDATE_DATE,
              :new.LINE_ID,
              :new.CHECK_INSERT_FLAG,
              v_show_error);
           end if;

               raise_application_error (-20001, 'Company Code does not exists!!  '||'Company code -'||:new.company_code||' ');
             --  Rollback;
           exception
            when others then
            raise_application_error (-20001, sqlerrm);
            null;
          end;
     end if; 

end;

【问题讨论】:

【参考方案1】:

第一种方式是autonomous transaction

第二种方式是compound trigger

【讨论】:

我正在尝试使用自主事务并将其保存到临时表中,但它也保存在主表中。如果数据存储在临时表中,则不应将其保存到主表中,因为用户将更正数据,然后再次上传。如果我在插入语句之后尝试 raise_application_error,那么它会为每条记录出错,并且不会将任何内容保存到主表中。 @user3849885 请给我看自治事务的代码

以上是关于在主表上的数据库触发器中将数据插入临时表的主要内容,如果未能解决你的问题,请参考以下文章

而不是所有表上的插入触发器

创建 MySQL 触发器以验证另一个表上的数据

2个表上的Oracle触发器:未找到任何数据

两个不同表上的 ORACLE SQL 触发器或存储过程

想写一个DB2触发器,几张表有关联,修改其中一张主表中的某一个字段,其他关联表中的该字段也跟着联动修改

如何编写 MySQL 触发器以将行插入另一个表?