Oracle 在快速刷新物化视图中使用非确定性函数真的是被禁止的吗?

Oracle 在快速刷新物化视图中使用非确定性函数真的是被禁止的吗?,oracle,oracle11g,Oracle,Oracle11g,如果我创建了一个物化视图快速刷新,其中包含一个虚拟列,而该列包含一个函数,则会引发一个错误,指出该函数应该是确定性的 我耍了个花招!我添加了function DETERMINISTIC关键字,尽管它不是,然后成功地创建了物化视图。之后,我从函数中删除了DETERMINISTIC关键字,物化视图就可以工作了 在虚拟列中使用非确定性函数并在具有快速刷新的物化视图中使用该虚拟列可以吗?物化视图是否仍能快速刷新?我认为在物化视图中创建虚拟列没有意义,这与物化视图的用途相矛盾 物化视图用于存储值,因为计算

如果我创建了一个物化视图快速刷新,其中包含一个虚拟列,而该列包含一个函数,则会引发一个错误,指出该函数应该是确定性的

我耍了个花招!我添加了function DETERMINISTIC关键字,尽管它不是,然后成功地创建了物化视图。之后,我从函数中删除了DETERMINISTIC关键字,物化视图就可以工作了


在虚拟列中使用非确定性函数并在具有快速刷新的物化视图中使用该虚拟列可以吗?物化视图是否仍能快速刷新?

我认为在物化视图中创建虚拟列没有意义,这与物化视图的用途相矛盾


物化视图用于存储值,因为计算或选择这些值会花费太多时间。因此,也应该存储来自虚拟列的值。

正如您已经了解到的,在表或物化视图中使用非确定性函数并不是严格禁止的。错误ORA-30553的要点是:该功能不是确定性的,是为了确保您永远不会创建在Oracle不知情的情况下可以更改的数据结构。如果Oracle无法跟踪表的更改,那么许多事情都可能会中断,例如索引和完整性约束

下面的示例显示了导致错误结果的函数更改。重新创建确定性函数以返回不同的结果违反了确定性函数的精神

我相信这也部分回答了你之前的问题,确定性函数什么时候使用之前的计算值?当它不重新验证约束或更新索引时,它始终隐式地使用该值

--#1: Simple deterministic function that returns 1. 
create or replace function not_deterministic return varchar2 deterministic is
begin
    return 'old value';
end;
/

--#2: Virtual table that uses the function and has an index on the function.
drop table deterministic_test;
create table deterministic_test(a char(100), b as (not_deterministic()) not null);
insert into deterministic_test(a) select 1 from dual connect by level <= 100000;
create index deterministic_test_index on deterministic_test(b);
begin
    dbms_stats.gather_table_stats(user, 'deterministic_test');
end;
/

--#3: All the values are 'old value'.
select distinct b from deterministic_test where a is not null;

b
-
old value

--#4: Change the function to return 'new value'.
create or replace function not_deterministic return varchar2 deterministic is
begin
    return 'new value';
end;
/

--#5: Indexes are not maintained leading to wrong, inconsistent results.
--Both should return 'new value'.
select distinct b from deterministic_test;

B
-
old value

select /*+full(deterministic_test)*/ distinct b from deterministic_test;

B
-
new value

尝试刷新一次:@San我已经重新编译并刷新了它,它工作了!更新或插入任何基表后是否刷新?如果没有,则刷新不起任何作用。请尝试执行DBMS\u MVIEW.EXPLAIN\u MVIEW'my\u mat\u view'。然后查看MV_CAPABILITIES_表。然后您应该检查view ALL_mview如果刷新成功、快速或完整,我没有在物化视图中创建虚拟列,我正在使用表中已定义的虚拟列。谢谢。事实上,我正在寻找一个示例来说明将非确定性函数定义为确定性函数的问题。你的答案肯定是其中之一。