公司项目里有一个存储过程,使用out参数返回一个游标。今天客户突然说这个存储过程有问题,于是研究了很久。最后发现存储过程中的select语句order by子句换一个字段就不报错了。也就是说同样的select语句,只是order by字句的字段不同,一个报错一个不抱错。
最后我分析的原因是,因为order by字段不同,oracle使用的索引不同,导致select语句的筛选条件先后顺序不一样。
一个是先把报错的数据筛选掉了,在查询值所以不报错。
另一个先查询值再筛选,而查询值时报错了。不知道我这样的解释是否正确,各位有没有遇到同样的问题?分不多,各位包含
最后我分析的原因是,因为order by字段不同,oracle使用的索引不同,导致select语句的筛选条件先后顺序不一样。
一个是先把报错的数据筛选掉了,在查询值所以不报错。
另一个先查询值再筛选,而查询值时报错了。不知道我这样的解释是否正确,各位有没有遇到同样的问题?分不多,各位包含
存储过程代码如下
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;
况且你说的换一个字段进行order by就不报错?可以告诉你 在select查询语句中 order by 永远都是最后才执行的
还有报错信息是什么?你分析过log吗?当你做了这些的时候再来考虑
分析问题必须先从报错点入手,log就是最直接的证据,你不分析log,区区换个字段排序就没问题了,可能吗?
嗯,我也很奇怪,但事实上是orderby换一个字段就不报错了。
而且很奇怪的是,把存储过程里面的select拿出来执行,怎么都是报错的。
报错信息是no data found,是GetPatientname这个函数里面报错,有的数据找不到记录。
这些我都找了,是有一个人没有数据。
但是orderby换个字段,还是没数据啊,可就不报错了。
所以我觉得是使用了不同的索引,先排除掉了没有数据的那行记录,再执行的getpatientname。
而且select语句拿出来执行,怎么都报错。
存储过程里面又看不到select语句的执行计划