我有一个函数如下,由于游标循环,性能非常差。我需要有人帮我摆脱光标并使用一个语句代替。任何人都可以提供帮助,非常感谢!!
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)获得最短日期
所以,我需要一种方法来摆脱游标循环(性能太差)并使用一个语句获得最终结果。
答案 0 :(得分:0)
以下内容可能会对您有所帮助。
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
select case when v_rst is null and B.transplant_date is not null then v_rst := v_transplant_date
when v_rst IS NOT NULL AND B.transplant_date is not null AND v_rst - v_transplant_date > 0 THEN v_rst := v_transplant_date
END
from (
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
) A
inner join (
select patr.patr_id, min(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
group by patr.patr_id
) B
on A.patr_id = B.patr_id
return v_rst;
答案 1 :(得分:0)
您对c_cur1
的查询似乎不正确。其结果不依赖于p_patr_id
参数
提到p_patr_id
的唯一位置是以下子查询:
(select pat.pat_id
from pat, pat_register patr
where patr.patr_id = p_patr_id)
此子查询的结果显然不依赖于p_patr_id
。 : - )