使用触发器刷新或更新物化视图时出错

时间:2016-08-03 12:05:03

标签: database oracle triggers materialized-views

我尝试了两种方法。 首先,我使用存储过程在触发器中调用。

CREATE OR REPLACE TRIGGER MV_BANK_CODE_UPDATE
AFTER UPDATE OR INSERT OR DELETE OF APPROVAL_STATUS ON BANK_CODES 
FOR EACH ROW
  BEGIN


     SP_UPDATE_MV_BANK_CODES;


  END;
/

存储过程:

CREATE OR REPLACE PROCEDURE SP_UPDATE_MV_BANK_CODES IS


BEGIN

DELETE  MV_BANK_CODES;
COMMIT;
INSERT  MV_BANK_CODES 
(SELECT DISTINCT
       bankcodeeo.clearing_area,
       bankcodeeo.bank_code,
       bankcodeeo.bank_code_id,
       bankcodeeo.bank_name,
       bankcodeeo.office_code,
       bankcodeeo.bank_address,
          oldaccounteo.office_code
       || '.'
       || oldaccounteo.gl_account_no
       || '.'
       || oldaccounteo.sl_account_no
       || '.'
       || oldaccounteo.currency_code
       || '.'
       || oldaccounteo.department_code
       || '.'
       || oldaccounteo.working_unit_code
       || '.'
       || oldaccounteo.project_code
          AS new_ind_account_no,
       /*tcgleo.*/
       '9' AS position,
       transactioncodeeo.transaction_code,
       oldaccounteo.gl_account_no,
       oldaccounteo.sl_account_no,
       oldaccounteo.currency_code,
       oldaccounteo.department_code,
       oldaccounteo.working_unit_code,
       oldaccounteo.project_code,
       oldaccounteo.old_ind_account_no,
       oldaccounteo.old_ind_account_name,
       transactioncodeeo.forex_type_flag,
       transactioncodeeo.forex_type,
       glaccounteo.gl_account_type AS classification_flag,
       bankcodeeo.member_code,
       oldaccounteo.category_code,
       glaccounteo.normal_position,
       transactioncodeeo.source_account_flag,
       transactioncodeeo.usage_forex,
       bankcodeeo.member_type,
       TRANSACTIONCODEEO.CURRENCY_TYPE
  FROM bank_codes bankcodeeo
       INNER JOIN old_accounts oldaccounteo
          ON     bankcodeeo.account_no = oldaccounteo.old_ind_account_no
             AND oldaccounteo.approval_status = '2'
             AND oldaccounteo.activation_status = '1'
       INNER JOIN gl_sl_accounts glsleo
          ON     glsleo.gl_account_no = oldaccounteo.gl_account_no
             AND glsleo.sl_account_no = oldaccounteo.sl_account_no
             AND glsleo.approval_status = '2'
             AND glsleo.activation_status = '1'
       INNER JOIN gl_accounts glaccounteo
          ON     glaccounteo.gl_account_no = glsleo.gl_account_no
             AND glaccounteo.approval_status = '2'
             AND glaccounteo.activation_status = '1'
       INNER JOIN tc_gl tcgleo
          ON tcgleo.gl_account_no = glaccounteo.gl_account_no
       INNER JOIN transaction_codes transactioncodeeo
          ON     transactioncodeeo.transaction_code = tcgleo.transaction_code
             AND transactioncodeeo.approval_status = '2'
             AND transactioncodeeo.activation_status = '1'
 WHERE bankcodeeo.approval_status = '2'
       AND bankcodeeo.activation_status = '1');

       COMMIT;

END;
/

当我更新表BANK_CODE时,出现错误:

ORA-01732: data manipulation operation not legal on this view 
ORA-06512: at "SP_UPDATE_MV_BANK_CODES", line 6 
ORA-06512: at "MV_BANK_CODE_UPDATE", line 3 
ORA-04088: error during execution of trigger 'MV_BANK_CODE_UPDATE'

其次,我使用DBMS_MVIEW.REFRESH

CREATE OR REPLACE TRIGGER MV_BANK_CODE_UPDATE_X
AFTER UPDATE OR INSERT OR DELETE OF APPROVAL_STATUS ON BANK_CODES 

FOR EACH ROW
  BEGIN

     DBMS_MVIEW.REFRESH('MV_BANK_CODES');

   END MV_BANK_CODE_UPDATE_X;
/

当我更新表BANK_CODE时,出现错误:

ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 3014
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2994
ORA-06512: at "MV_BANK_CODE_UPDATE_X", line 3
ORA-04088: error during execution of trigger 'MV_BANK_CODE_UPDATE_X'

我该怎么办?

1 个答案:

答案 0 :(得分:0)

我可以理解你的要求,只要在表BANK_CODES上发生任何dml操作,你就需要刷新物化视图MV_BANK_CODES。

你必须注意几点

  1. 首先,不需要手动编写代码来使用触发器刷新MV。
  2. 我们无法在触发器中执行提交/回滚。
  3. DBMS_MVIEW.REFRESH隐式提交,因此无法提交内部触发器
  4. BAD解决方案:    你可以通过在触发器中使用PRAGMA AUTONOMOUS块来实现它,它将MV中的插入/更新/删除视为单独的事务,因此mv将具有未提交的数据,并且如果之后某些事情失败,则mv数据将不会被回滚

    优先解决方案: 现在,如果要刷新实体化视图,则需要了解如何定义实体化视图Documentation Materialized View Refresh

    create materialized view MV_BANK_CODES
      REFRESH FAST ON COMMIT
    AS 
       SELECT DISTINCT
           bankcodeeo.clearing_area,
           bankcodeeo.bank_code,
           bankcodeeo.bank_code_id,
           bankcodeeo.bank_name,