Oracle11g 存储物化视图中的数据

Oracle11g 存储物化视图中的数据,oracle11g,materialized-views,Oracle11g,Materialized Views,我有一个物化的viewMV,每天23:00刷新。它将从大型交易表(例如1亿条记录)中进行选择,并汇总用于报告目的的数据 MV非常简单,只包含4列和7条记录。每次用户生成报告时,它都会显示MV中的数据。现在用户请求能够查看去年的数据。由于我的MV总是替换现有数据,我无法实现用户请求 我的问题 1.是否可以将MV中的数据自动存储在持久表中? 2.每次MV刷新完成时,创建触发器将MV中的数据插入另一个表是否可行?实体化视图没有触发器。然而,可更新的物化视图确实有触发器,但它有一个陷阱,它必须基于单个表

我有一个物化的viewMV,每天23:00刷新。它将从大型交易表(例如1亿条记录)中进行选择,并汇总用于报告目的的数据

MV非常简单,只包含4列和7条记录。每次用户生成报告时,它都会显示MV中的数据。现在用户请求能够查看去年的数据。由于我的MV总是替换现有数据,我无法实现用户请求

我的问题 1.是否可以将MV中的数据自动存储在持久表中?
2.每次MV刷新完成时,创建触发器将MV中的数据插入另一个表是否可行?

实体化视图没有触发器。然而,可更新的物化视图确实有触发器,但它有一个陷阱,它必须基于单个表

基于多个表

ORA-12013:可更新的物化视图必须足够简单,以便进行快速刷新

基于单表

触发

CREATE OR REPLACE TRIGGER test_tg
   BEFORE INSERT OR UPDATE OF ENAME, MGR
   ON MV_TEST
   REFERENCING NEW AS New OLD AS Old
   FOR EACH ROW
DECLARE
   tmpVar   NUMBER;
BEGIN
   tmpVar := 0;


   NULL;
    -- do as per the logic
EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
      -- Consider logging the error and then re-raise
      RAISE;
END test_tg;

Trigger created.

如果要求有历史数据,为什么不考虑一个标准事务表来使用可使用调度器作业执行的存储过程来保持数据持久性。

正如您所引用的查询一个有1亿个记录的大表,我的估计是使用FALL全部或批量收集或考虑批次处理,不用说;这是另一个话题

以下是过程和调度程序作业的伪代码,请根据需要进行更改。使用插入或合并

使用INSERT的过程

使用合并的过程

调度程序作业


据我所知,物化视图没有触发器。如果要求是有历史数据的,那么为什么不考虑使用一个可以使用调度器作业来执行数据存储的标准事务表,Hij@ Jo.COB,非常感谢您的澄清。我将沿着这个方向走。你能回答这个问题吗?这样我就可以把这个标记为正确答案了?
CREATE MATERIALIZED VIEW mv_test
   REFRESH FAST WITH PRIMARY KEY
   FOR UPDATE
AS
   SELECT * FROM emp;

Materialized View created.
CREATE OR REPLACE TRIGGER test_tg
   BEFORE INSERT OR UPDATE OF ENAME, MGR
   ON MV_TEST
   REFERENCING NEW AS New OLD AS Old
   FOR EACH ROW
DECLARE
   tmpVar   NUMBER;
BEGIN
   tmpVar := 0;


   NULL;
    -- do as per the logic
EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
      -- Consider logging the error and then re-raise
      RAISE;
END test_tg;

Trigger created.
CREATE OR REPLACE PROCEDURE historical_records (p_emp_no emp.empno%TYPE)
IS
BEGIN
   FOR rec IN (  SELECT ename, mgr, SUM (sal) tot_sal
                   FROM scott.emp
                  WHERE empno = p_emp_no
               GROUP BY ename, mgr)
   LOOP
      INSERT INTO hist_table (empno,
                              ename,
                              mgr,
                              sal_tot)
           VALUES (rec.empno,
                   rec.ename,
                   rec.mgr,
                   rec.tot_sal);
   END LOOP;
END;
CREATE OR REPLACE PROCEDURE historical_records (p_emp_no emp.empno%TYPE)
IS
BEGIN
   MERGE INTO hist_table trg
        USING (  SELECT ename, mgr, SUM (sal) tot_sal
                   FROM scott.emp
                  WHERE empno = p_emp_no
               GROUP BY ename, mgr) src
           ON (trg.empno = src.empno)
   WHEN MATCHED
   THEN
      UPDATE SET trg.ename = src.ename, trg.mgr = src.mgr
   WHEN NOT MATCHED
   THEN
      INSERT     (trg.empno, trg.ename, trg.sal_tot)
          VALUES (src.empno, src.ename, src.tot_sal);
END;
BEGIN
   DBMS_SCHEDULER.CREATE_JOB (
      job_name          => 'HIST_PROC_JOB',
      job_type          => 'PLSQL_BLOCK',
      JOB_ACTION        => 'BEGIN historical_records; END;',
      start_date        => SYSDATE,
      repeat_interval   => 'FREQ=DAILY;BYHOUR=23;BYMINUTE=05',
      end_date          => NULL,
      enabled           => TRUE,
      comments          => 'Historical data insertion');
END;
/