如果我创建一个物化视图(快速刷新),该视图包含一个virtual column,而该列包含一个函数,则会引发一个错误,说明该函数应该是DETERMINISTIC。
我做了个小把戏!我添加了函数DETERMINISTIC关键字(尽管它不是),然后成功地创建了物化视图。之后,我从函数中删除了DETERMINISTIC关键字,物化视图就可以工作了。
在虚拟列中有一个非确定性函数,并在物化视图中使用该虚拟列,并进行快速刷新,可以吗?物化视图是否仍然快速刷新?
发布于 2014-01-29 06:38:19
在表或物化视图中使用非确定性函数并不是严格禁止的,因为您已经知道了。错误ORA-30553: The function is not deterministic的目的是确保您永远不会在不知道的情况下创建一个可以更改的数据结构。如果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发布于 2014-01-28 12:35:06
我认为在物化视图中创建虚拟列是没有意义的,这与物化视图的目的相矛盾。
物化视图用于存储值,计算或选择它们需要花费太多时间。因此,还应该存储从虚拟列开始的值。
https://stackoverflow.com/questions/21404342
复制相似问题