目标:
电信号码表,
查询最大数,
条件中需要用到一个函数索引。说明:
在普通的SQL窗口中运行该查询,没有问题,使用了索引,速度比较快,但是在存储过程中使用该语句对应的语句就会非常的慢,大家帮忙看看是什么原因。语句:
SELECT MAX(PhonesID)
INTO t_sTempnum
FROM qry_phones
WHERE FN_TRN_NUMBER(PhonesID) IS NOT NULL;函数也也是非常的简单,就是进行异常处理,去掉无用的数据。
CREATE OR REPLACE FUNCTION FN_TRN_NUMBER(i_vValue IN VARCHAR2)
RETURN NUMBER DETERMINISTIC
IS
RESULT NUMBER;
BEGIN
BEGIN
RESULT := TO_NUMBER(i_vValue);
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;建索引:
create index XIE15QRY_PHONES on QRY_PHONES ("CCATS114"."FN_TRN_NUMBER"(TO_CHAR(PHONESID)));调用的存储过程可以类似的写成:
CREATE OR REPLACE PROCEDURE test_fn IS
t_sMaxid INTEGER;
BEGIN
SELECT MAX(PhonesID)
INTO t_sMaxid
FROM qry_phones
WHERE FN_TRN_NUMBER(PhonesID) IS NOT NULL;
END test_fn;=========================是不是在存储过程中,不能使用函数索引呢?还请各位多多指教。
RETURN(RESULT);
END FN_TRN_NUMBER;

解决方案 »

  1.   

    储存过程中不能这样使用动态的sql语句。你的索引中使用了自定义函数,它是动态的,sql查询窗口中可以使用,在过程中确实不行的。建议,为加快速度,建立的索引是简单的、明确的、包含所有记录的,查询时排除不需要的纪录。
      

  2.   

    我的那个函数就是用来排除无用的数据的,ID中由于可能有一些脏数据,可能会有一些不是数字的字符串ID,所以使用一个自定义函数,这个函数,我已经定义成了静态的,添加了标识“DETERMINISTIC”,其它的字段没有可以用来过滤的了。
    是不是存储过程中就不能用函数索引呢?
      

  3.   

    从来没听过procedure不能使用函数索引.
    楼主还是从其它方面考虑问题
      

  4.   

    问题解决了,存储过程和直接执行SQL的确是有差别的,自定义的函数索引在存储过程中没有被利用,没有什么其它的原因,问题已经结觉得,其实解决问题的方式大家也都知道,也非常的简单,既然没有用索引,那我就使用强制索引的提示:
    SELECT /*+ INDEX (QRY_PHONES XIE15QRY_PHONES) */
     MAX(PhonesID)
      FROM qry_phones
     WHERE FN_TRN_NUMBER(PhonesID) IS NOT NULL
    ------------------------------------------------
    存储过程中也就如强制索引提示
        SELECT /*+ INDEX (QRY_PHONES XIE15QRY_PHONES) */  
           MAX(PhonesID)
          INTO t_sMaxid
          FROM qry_phones
         WHERE FN_TRN_NUMBER(PhonesID) IS NOT NULL;一切问题都解决了,100万的数据只用了1秒,而且还是我的手提电脑上的数据库。
    谢谢大家的抛砖引玉。