-
--自定义函数使用函数索引要注意函数代码改变后的影响。
-
DROP TABLE t;
-
CREATE TABLE t ( x NUMBER, y VARCHAR2(30));
-
-
INSERT INTO t SELECT ROWNUM, ROWNUM || \'a\' FROM dual CONNECT BY ROWNUM < 1000;
-
-
CREATE OR REPLACE PACKAGE pkg_f
-
IS
-
FUNCTION f(p_value VARCHAR2) RETURN VARCHAR2 DETERMINISTIC;
-
END;
-
/
-
-
create or REPLACE package body pkg_f
-
is
-
function f(p_value varchar2) return VARCHAR2 deterministic is
-
begin
-
return p_value;
-
end;
-
end;
-
/
-
-
create index idx_pkg_f_y on t ( pkg_f.f(y));
-
analyze table t compute statistics for table for all indexes for all indexed columns;
-
set autotrace on explain
-
SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';
-
-
X Y
-
---------- ------------------------------
-
8 8a
-
--修改包的定义
-
create or REPLACE package body pkg_f
-
is
-
function f(p_value varchar2) return VARCHAR2 deterministic
-
is
-
begin
-
return p_value||\'b\';
-
end;
-
end;
-
/
-
-
--惊奇地发现查询出错误的值:
-
SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';
-
-
X Y
-
---------- ------------------------------
-
8 8a
-
--重建索引,再次查询,得到正确的结果
-
drop index idx_pkg_f_y;
-
create index idx_pkg_f_y on t ( pkg_f.f(y));
-
SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';
-
-
luise@TESTDB11>SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';
-
-
no rows selected
--这里使用的是包中定义的函数,独立函数也是如此。
--结论:使用函数索引一定要注意在函数代码修改后,一定要重建函数索引.
-- 否则Oracle就会使用原来的函数索引查询出错误的结果,而没有任何提示
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17013648/viewspace-1071280/
,如需转载,请注明出处,否则将追究法律责任。