【问题标题】:Error refresh or update materialized view using trigger使用触发器刷新或更新物化视图时出错
【发布时间】:2016-12-09 03:35:24
【问题描述】:

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

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'

我该怎么办?

【问题讨论】:

    标签: database oracle triggers materialized-views


    【解决方案1】:

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

    你必须注意的几点

    1. 首先无需手动编写代码来使用触发器刷新 MV。
    2. 我们无法在触发器中执行提交/回滚。
    3. DBMS_MVIEW.REFRESH 隐式提交,因此无法在触发器内提交

    糟糕的解决方案: 您可以通过在触发器中使用 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,
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 2017-06-07
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2011-07-09
    相关资源
    最近更新 更多