在oracle里建了一个包,定义了一个游标类型在包里定义了一个函数,返回类型为刚才定义的游标类型在函数中根据函数输入参数动态生成游标并open这个游标在函数外读取这个游标现在遇到的问题是,当open游标时查询条件写死的话(即不使用变量),函数外取这个游标的速度就非常快如果open游标时查询条件用变量写的话(实际生成的sql和上面是一样的),函数外取这个游标的速度就非常慢前者的速度在0.1s以内,后者的速度在20s左右,差别很明显
而且函数的运行速度是一样的,只是读取这个返回游标的速度不一样
请问有人遇到过类似情况吗?知道是什么原因造成的吗?先谢了

解决方案 »

  1.   

    前者的代码:
    open cur for SELECT
        c.QJ ALLBUREAUNAME,b.a_user_id,b.bureau_id,c.FJ DISBUREAUNAME,b.USER_NAME USER_NAME,b.E_ADSL_ID E_ADSL_ID,b.U_ADSL_ID U_ADSL_ID,b.BIND_TEL BIND_TEL,b.LINK_TEL LINK_TEL,b.ADDRESS ADDRESS, b.USER_TYP USER_TYP,b.EQU_TYP EQU_TYP,b.SERV_TYP SERV_TYP, b.SERV_RATE SERV_RATE,b.SIGNED SIGNED,d.sign_person_id
      FROM t_adsl_users b,v_bureau c,t_deploy_info d
         WHERE b.BUREAU_ID like 'B00%'  AND
               b.USER_NAME like '%'  and
     (b.U_ADSL_ID like 'ad50606929') AND
               b.BUREAU_ID=c.BUREAU_ID AND 
               b.a_user_id=d.a_user_id(+);
    后者的代码:
    open cur for SELECT
        c.QJ ALLBUREAUNAME,b.a_user_id,b.bureau_id,c.FJ DISBUREAUNAME,b.USER_NAME USER_NAME,b.E_ADSL_ID E_ADSL_ID,b.U_ADSL_ID U_ADSL_ID,b.BIND_TEL BIND_TEL,b.LINK_TEL LINK_TEL,b.ADDRESS ADDRESS, b.USER_TYP USER_TYP,b.EQU_TYP EQU_TYP,b.SERV_TYP SERV_TYP, b.SERV_RATE SERV_RATE,b.SIGNED SIGNED,d.sign_person_id
      FROM t_adsl_users b,v_bureau c,t_deploy_info d
         WHERE b.BUREAU_ID like 'allbureau_id_tmp'  AND
               b.USER_NAME like 'username_tmp'  and
     (b.U_ADSL_ID like 'telephone_temp') AND
               b.BUREAU_ID=c.BUREAU_ID AND 
               b.a_user_id=d.a_user_id(+);
      

  2.   

    后者的代码:
    open cur for SELECT
        c.QJ ALLBUREAUNAME,b.a_user_id,b.bureau_id,c.FJ DISBUREAUNAME,b.USER_NAME USER_NAME,b.E_ADSL_ID E_ADSL_ID,b.U_ADSL_ID U_ADSL_ID,b.BIND_TEL BIND_TEL,b.LINK_TEL LINK_TEL,b.ADDRESS ADDRESS, b.USER_TYP USER_TYP,b.EQU_TYP EQU_TYP,b.SERV_TYP SERV_TYP,b.SERV_RATE SERV_RATE,b.SIGNED SIGNED,d.sign_person_id
      FROM t_adsl_users b,v_bureau c,t_deploy_info d
         WHERE b.BUREAU_ID like allbureau_id_tmp  AND
               b.USER_NAME like username_tmp  and
     (b.U_ADSL_ID like telephone_temp) AND
               b.BUREAU_ID=c.BUREAU_ID AND 
               b.a_user_id=d.a_user_id(+);
    ------『不好意思,刚刚后者的where条件中多了单引号。』
      

  3.   

    你这个语句有问题啊,telephone_temp是一个变量吧,语句不应该这样写的啊,应该不能运行的,另外,你后者的语句中telephone_temp是否有多个值从而导致了后者的查询语句其实运行了多次所以时间慢?或者计算telephone_temp的值的那个函数运行的慢,单从后者的查询语句来看没有问题,慢的原因一定在其它地方。
      

  4.   

    后者的代码這樣試試:
    declare v_telephone_temp;
    declare cursor V_CUR(telephone_temp) is
    SELECT....(b.U_ADSL_ID like telephone_temp) AND..,;
    begin
     v_telephone_temp :='KK%';
    open V_CUR(v_telephone_temp);
    ...
    exception...
    end; 
      

  5.   

    这个函数是可以运行的。telephone_temp 就只有一个值,而且这个值是当作参数传进来的,我test这个函数的时候,给这个参数telephone_temp赋的值就是 “前者”代码中写死的值,即:'ad50606929'。这个函数是一个查询动作,并且把结果集以游标的形式返回。
    现在的问题是:
    test这个函数时,
    如果使用“前者的代码”(在这个代码块中,where条件的数据是“明文”写在代码中的),此时,从函数外取这个游标的速度非常快,0.1S还不到。如果使用“后者的代码”(在这个代码块中,把数据赋值在参数中,并在where条件中使用这个被赋了值的参数),此时,从函数外取这个游标的速度就非常慢,20S左右
      

  6.   

    to:shyming
       还是不行。
      

  7.   

    后者的代码:
    open cur for SELECT
        c.QJ ALLBUREAUNAME,b.a_user_id,b.bureau_id,c.FJ DISBUREAUNAME,b.USER_NAME USER_NAME,b.E_ADSL_ID E_ADSL_ID,b.U_ADSL_ID U_ADSL_ID,b.BIND_TEL BIND_TEL,b.LINK_TEL LINK_TEL,b.ADDRESS ADDRESS, b.USER_TYP USER_TYP,b.EQU_TYP EQU_TYP,b.SERV_TYP SERV_TYP,b.SERV_RATE SERV_RATE,b.SIGNED SIGNED,d.sign_person_id
      FROM t_adsl_users b,v_bureau c,t_deploy_info d
         WHERE b.BUREAU_ID like allbureau_id_tmp  AND
               b.USER_NAME like username_tmp  and
     (b.U_ADSL_ID like telephone_temp) AND
               b.BUREAU_ID=c.BUREAU_ID AND 
               b.a_user_id=d.a_user_id(+);
    这个后者的代码到底哪几个是变量啊, 看不清... 列名与变量在一起, 分不清~~~
    allbureau_id_tmp,username_tmp,username_tmp,telephone_temp这四个吗???是值的话, 不能这样写, 要用bind parameter~
      

  8.   

    “后者代码”三个变量:
    allbureau_id_tmp
    username_tmp
    telephone_temp在前者代码中,我分别把这三个变量改为实际的值:
    'B00%'
    '%'
    'ad50606929'