ITPub博客

首页 > 数据库 > Oracle > 函数索引陷阱

函数索引陷阱

原创 Oracle 作者:LuiseDalian 时间:2014-01-16 08:48:45 0 删除 编辑

点击(此处)折叠或打开

  1. --自定义函数使用函数索引要注意函数代码改变后的影响。
  2. DROP TABLE t;
  3. CREATE TABLE t ( x NUMBER, y VARCHAR2(30));

  4. INSERT INTO t SELECT ROWNUM, ROWNUM || \'a\' FROM dual CONNECT BY ROWNUM < 1000;

  5. CREATE OR REPLACE PACKAGE pkg_f
  6. IS
  7.   FUNCTION f(p_value VARCHAR2) RETURN VARCHAR2 DETERMINISTIC;
  8. END;
  9. /

  10. create or REPLACE package body pkg_f
  11. is
  12.   function f(p_value varchar2) return VARCHAR2 deterministic is
  13.   begin
  14.     return p_value;
  15.   end;
  16. end;
  17. /

  18. create index idx_pkg_f_y on t ( pkg_f.f(y));
  19. analyze table t compute statistics for table for all indexes for all indexed columns;
  20. set autotrace on explain
  21. SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';

  22.          X Y
  23. ---------- ------------------------------
  24.            8 8a



点击(此处)折叠或打开

  1. --修改包的定义
  2. create or REPLACE package body pkg_f
  3. is
  4.   function f(p_value varchar2) return VARCHAR2 deterministic
  5.   is
  6.   begin
  7.     return p_value||\'b\';
  8.   end;
  9. end;
  10. /

  11. --惊奇地发现查询出错误的值:
  12. SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';

  13.          X Y
  14. ---------- ------------------------------
  15.            8 8a



点击(此处)折叠或打开

  1. --重建索引,再次查询,得到正确的结果
  2. drop index idx_pkg_f_y;
  3. create index idx_pkg_f_y on t ( pkg_f.f(y));
  4. SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';

  5. luise@TESTDB11>SELECT * FROM t WHERE pkg_f.f(y)= \'8a\';

  6. no rows selected


--这里使用的是包中定义的函数,独立函数也是如此。

--结论:使用函数索引一定要注意在函数代码修改后,一定要重建函数索引.

--      否则Oracle就会使用原来的函数索引查询出错误的结果,而没有任何提示

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17013648/viewspace-1071280/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 小心保留字
下一篇: 标量子查询(一)
请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    1986
  • 访问量
    6040880