Материализованные представления не имеют триггеров.Тем не менее, обновляемое материализованное представление имеет триггеры, но оно имеет подвох, оно должно основываться на одной таблице.
На основе более чем одной таблицы
CREATE MATERIALIZED VIEW LOG ON EMP;
CREATE MATERIALIZED VIEW mv_test
REFRESH FAST WITH PRIMARY KEY
FOR UPDATE
AS
SELECT *
FROM emp em JOIN DEPT de ON EM.DEPTNO = DE.DEPTNO;
ORA-12013: обновляемые материализованные представления должны быть достаточно простыми для быстрого обновления
На основе одной таблицы
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.
Если требуется наличие хронологических данных, почему бы не рассмотреть стандартную транзакционную таблицу для сохранения данных с использованием хранимой процедуры, которую можно выполнить с помощью заданий планировщика.
Как у вас естьпроцитировал запрос к большой таблице, в которой есть 100 миллионов записей, я рассчитывал бы использовать FOLL ALL
или BULK COLLECT
или рассмотреть возможность пакетной обработки, разумеется;это другая тема.
Ниже приведены псевдокоды для процедур и заданий планировщика, вносите изменения по мере необходимости.Или используйте INSERT или MERGE
Процедура с использованием INSERT
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;
Процедура с использованием MERGE
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;
/