我有一个如下所示的函数,由于光标循环,它的性能非常差。我需要有人帮我摆脱光标并改用一个语句。任何人都可以提供帮助将不胜感激!
function get_pat_liv_donor_trans_date(p_patr_id IN NUMBER) return date is
v_transplant_date date;
v_rst date;
v_patr_id number;
--get patient all the patr_id(s) which has been transplanted (kidney) with living donor
cursor c_cur1 is
select distinct patr.patr_id
from pat,
pat_register patr,
pat_register_org_det prod,
transplant_org_det tod,
transplant trans,
don,
don_org_con doc,
allo,
all_pat_list apl,
ORG_SPEC OS,
DON_ORG_OFF_RES DOOR
where pat.pat_id = patr.pat_id
and patr.patr_id = prod.patr_id
and prod.prod_id = tod.prod_id --patient has been transplanted (kidney)
and tod.orgsp_id in (5, 6, 7, 8, 9) --5:Kidney-Unknown, 6:Kidney-Right, 7:Kidney-Left, 8:Kidney-Both, 9:Kidney-Single
and trans.patr_id = patr.patr_id
and don.don_id = doc.don_id
and doc.doc_id = allo.doc_id
and allo.all_id = apl.all_id
and apl.prod_id = prod.prod_id
and don.cadaveric_flg = 'N' --living donor
and OS.ORGSP_ID = DOOR.ORGSP_ID
AND DOOR.ACCEPT_IND = 'Y'
AND DOOR.ACCEPT_CANCEL_DATE IS NULL
AND APL.APL_ID = DOOR.APL_ID
and pat.pat_id in (select pat.pat_id
from pat, pat_register patr
where patr.patr_id = p_patr_id)
and patr.patr_id not in -- Not suspend registration
(select patr_id from pat_register_suspend where end_date is null)
--Not canceled registration
and patr.exp_date is null;
--get patient transplant_date which has been transplanted (kidney) with living
cursor c_cur2 is
select min(distinct trans.transplant_date)
from pat,
pat_register patr,
pat_register_org_det prod,
transplant_org_det tod,
transplant trans,
don,
don_org_con doc,
allo,
all_pat_list apl,
ORG_SPEC OS,
DON_ORG_OFF_RES DOOR
where pat.pat_id = patr.pat_id
and patr.patr_id = prod.patr_id
and prod.prod_id = tod.prod_id --patient has been transplanted (kidney)
and tod.orgsp_id in (5, 6, 7, 8, 9) --5:Kidney-Unknown, 6:Kidney-Right, 7:Kidney-Left, 8:Kidney-Both, 9:Kidney-Single
and trans.patr_id = patr.patr_id
and don.don_id = doc.don_id
and doc.doc_id = allo.doc_id
and allo.all_id = apl.all_id
and apl.prod_id = prod.prod_id
and patr.patr_id = v_patr_id
and don.cadaveric_flg = 'N' --living donor
and OS.ORGSP_ID = DOOR.ORGSP_ID
AND DOOR.ACCEPT_IND = 'Y'
AND DOOR.ACCEPT_CANCEL_DATE IS NULL
AND APL.APL_ID = DOOR.APL_ID;
begin
--if patient current is Not waiting for pancreas
if (tttt_kp_allocation.is_pat_waiting_for_pancreas(p_patr_id) != 'Y') then
return v_rst;
end if;
open c_cur1;
loop
fetch c_cur1
into v_patr_id;
exit when c_cur1%notfound;
open c_cur2;
fetch c_cur2
into v_transplant_date;
if (v_rst is null) and (v_transplant_date is not null) then
v_rst := v_transplant_date;
end if;
--get earlier of Date of Living Donor transplant for PAK
if (v_rst is not null) and (v_transplant_date is not null) then
if (v_rst - v_transplant_date > 0) then
v_rst := v_transplant_date;
end if;
end if;
close c_cur2;
end loop;
close c_cur1;
return v_rst;
end;
c_cur1 将返回如下:
patr_id
1001
1002
1003
1004
c_cur2 将返回一个日期,如:
2001-jan-01 ( patr_id : 1001)
2002-jan-01 ( patr_id : 1002)
2003-jan-01 ( patr_id : 1003)
2004-jan-01 ( patr_id : 1004)
最终结果v_rst
将获得从 (2001-jan-01, 2002-jan-01, 2003-jan-01, 2004-jan-01) 开始的最短日期
所以,我需要一种方法来摆脱游标循环(性能太差)并使用一条语句获得最终结果。