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

时间:2014-01-28 11:26:56

标签: oracle oracle11g

如果我创建一个包含virtual column的物化视图(快速刷新)并且该列包含一个函数,则会引发一个错误,指出该函数应为DETERMINISTIC

我做了一招!我添加了函数DETERMINISTIC关键字(虽然不是),然后成功创建了物化视图。之后我从函数中删除了DETERMINISTIC关键字,并且物化视图正常工作。

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

2 个答案:

答案 0 :(得分:2)

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

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

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

--#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

答案 1 :(得分:0)

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

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