公司项目里有一个存储过程,使用out参数返回一个游标。今天客户突然说这个存储过程有问题,于是研究了很久。最后发现存储过程中的select语句order by子句换一个字段就不报错了。也就是说同样的select语句,只是order by字句的字段不同,一个报错一个不抱错。
最后我分析的原因是,因为order by字段不同,oracle使用的索引不同,导致select语句的筛选条件先后顺序不一样。
一个是先把报错的数据筛选掉了,在查询值所以不报错。
另一个先查询值再筛选,而查询值时报错了。不知道我这样的解释是否正确,各位有没有遇到同样的问题?分不多,各位包含

解决方案 »

  1.   

    贴上全部信息,比如cursor的select语句是什么样的,对应的表结构情况,索引情况
      

  2.   

    不是我不愿意贴出来,实在是表结构太复杂了
    存储过程代码如下
    open out_cursor for
          Select a.PATIENT_ID,
                 nvl(a.PATIENTIDDISPLAY, '-') "Patient ID",
                 (select ts.site_name from  t_site ts where ts.site_id= c.site_id
                  and ts.lan_id = pni_lan_ID) as "SiteName",
                  GetPatientcreated(a.patient_ID) as "Create",
                  GetPatientDoctor(a.patient_ID) as "doctor",
                 'PatientNumber::'||GetPatientNumber(a.PATIENT_ID)||'@@@'||
                 'Patientname::'||GetPatientname(a.patient_ID)||'@@@'||
                 'Birth::'||GetPatientBirthorage(a.PATIENT_ID)||'@@@'||
                 'vaccination::'||GetPatientvaccination(a.patient_ID) as "patientinformation",
                 GetPatientstatus(a.patient_ID) as "patientstate",
                 GetPatientstartdoing(a.patient_ID) as "startdoing",
                 GetPatientsubmitday(a.patient_ID) as "submitday",
                 GetPatientesign(a.patient_ID) as "esign"
            from MGZ_DASHBOARD_PATIENT_INFO a,
                 m_user                     b,
                 l_site_users               c,
                 r_site_identifier          rsi,
                 r_item                     ri
           where a.Site_ID >= 10000
             and a.Site_ID = c.site_id
             and c.site_ID = rsi.SiteID
             and c.user_id = pin_user_id
             and a.Patient_ID = b.user_id
             and a.Lan_ID = pni_lan_ID
             and a.patient_ID = ri.item_id
             and ri.state_id != 36
             and (a.patientiddisplay is null or a.patientiddisplay not like '%M%')
           order by a.patientiddisplay;
      

  3.   

    我觉得你是错了的,是否走索引或者走什么样的index是跟你order by 哪个字段没关系,只跟你where条件有关
    况且你说的换一个字段进行order by就不报错?可以告诉你 在select查询语句中 order by 永远都是最后才执行的
      

  4.   

    问题的根本原因不在你order by哪个字段,楼主你明白了吗?
    还有报错信息是什么?你分析过log吗?当你做了这些的时候再来考虑
    分析问题必须先从报错点入手,log就是最直接的证据,你不分析log,区区换个字段排序就没问题了,可能吗?
      

  5.   

    没看懂  实在不行 在原有基础外包一层  再order by
      

  6.   


    嗯,我也很奇怪,但事实上是orderby换一个字段就不报错了。
    而且很奇怪的是,把存储过程里面的select拿出来执行,怎么都是报错的。
      

  7.   


    报错信息是no data found,是GetPatientname这个函数里面报错,有的数据找不到记录。
      

  8.   

    你排序的字段有问题,不是oracle的问题~
      

  9.   


    这些我都找了,是有一个人没有数据。
    但是orderby换个字段,还是没数据啊,可就不报错了。
    所以我觉得是使用了不同的索引,先排除掉了没有数据的那行记录,再执行的getpatientname。
    而且select语句拿出来执行,怎么都报错。
    存储过程里面又看不到select语句的执行计划