kov*_*sue 4 oracle plsql oracle19c
大家好,Stackoverflowers 的朋友们,
TLDR:MVIEW 是否正在使用UPDATE或DELETE + INSERT在刷新期间?
前一段时间,当我在 Oracle 中摆弄物化视图时,遇到了一件晦涩难懂的事情。这是我的例子:
这是一个示例代码:
-- ========================= DDL section =========================
/* drop tables */
drop table tko_mview_test_tb;
drop table tko_mview_test2_tb;
/* drop mview */
drop materialized view tko_mview_test_mv;
/* create tables */
create table tko_mview_test_tb as
select 1111 as id, 'test' as code, 'hello world' as data, sysdate as timestamp from dual
union
select 2222, 'test2' as code, 'foo bar', sysdate - 1 from dual;
create table tko_mview_test2_tb as
select 1000 as id, 'test' as fk, 'some string' as data, sysdate as timestamp from dual;
/* create table PKs */
alter table tko_mview_test_tb
add constraint mview_test_pk
primary key (id);
alter table tko_mview_test2_tb
add constraint mview_test2_pk
primary key (id);
/* create mview logs */
create materialized view log
on tko_mview_test_tb
with rowid, (data);
create materialized view log
on tko_mview_test2_tb
with rowid, (data);
/* create mview */
create materialized view tko_mview_test_mv
refresh fast on commit
as select a.code
, a.data
, b.data as data_b
, a.rowid as rowid_a
, b.rowid as rowid_b
from tko_mview_test_tb a
join tko_mview_test2_tb b on b.fk = a.code;
/* create mview PK */
alter table tko_mview_test_mv
add constraint mview_test3_pk
primary key (code);
Run Code Online (Sandbox Code Playgroud)
根据dbms_mview.explain_mview我的MVIEW是否能够快速刷新。
在这种特殊情况下(此处未举例),MVIEW 由其他表中的 FK 引用。因此,我发现,当我对这些基表之一进行更改并触发 MVIEW 刷新时,我收到一条错误消息:
ORA-12048: error encountered while refreshing materialized view "ABC"
ORA-02292: integrity constraint (ABC_FK) violated
Run Code Online (Sandbox Code Playgroud)
我当时想什么鬼?。所以我开始挖掘 - 我在 MVIEW 上创建了一个触发器。像这样的东西:
ORA-12048: error encountered while refreshing materialized view "ABC"
ORA-02292: integrity constraint (ABC_FK) violated
Run Code Online (Sandbox Code Playgroud)
所以我能够看到发生了什么。根据我的触发器,每次我在基表中执行UPDATE (不是 INSERT 或 DELETE)时,实际上都会对 MVIEW 表进行DELETE 和 INSERT操作。
/* create trigger on MVIEW */
create or replace trigger tko_test_mview_trg
after insert or update or delete
on tko_mview_test_mv
referencing old as o new as n
for each row
declare
begin
if updating then
dbms_output.put_line('update');
elsif inserting then
dbms_output.put_line('insert');
elsif deleting then
dbms_output.put_line('delete');
end if;
end tko_test_mview_trg;
/
Run Code Online (Sandbox Code Playgroud)
输出
delete
insert
Run Code Online (Sandbox Code Playgroud)
这是 MVIEW 刷新的正确工作方式吗?刷新MVIEW时MVIEW表没有更新?
问候,汤姆
小智 5
从 oracle 12.1 升级到 oracle 19.x 后我们看到了相同的行为
新创建的 mview 似乎表现相同,在刷新期间删除/插入,而不是“预期”更新。不确定它是坏还是错......但它可以“修复”。
应用补丁 30781970(不要忘记 _fix_control)并重新创建 mview......
参考:Bug 30781970 - MVIEW 刷新因 MVIEW 上存在触发器而出现 ORA-1 错误而失败(文档 ID 30781970.8)
| 归档时间: |
|
| 查看次数: |
2013 次 |
| 最近记录: |