| Oracle FAQ | Your Portal to the Oracle Knowledge Grid | |
Home -> Community -> Usenet -> c.d.o.misc -> Re: Performance issue in a function
Hi Brian,
As you said, i tried tuning my cursors in the function. here is my
function.
CREATE OR REPLACE FUNCTION GET_DM_AMOUNT (P_DM_NUMBER NUMBER
,P_MFR_ID NUMBER DEFAULT NULL
) RETURN NUMBER
IS
vn_amount Number;
vr_eb EXP_BATCH%ROWTYPE;
vr_dm EXP_DEBIT_MEMO%ROWTYPE;
CURSOR mfr_phy_returns_cur IS
SELECT SUM(extended_price) price
FROM exp_order_lines
WHERE order_line_id IN
(SELECT order_line_id FROM exp_contents_of_bag WHERE
container_id IN
(SELECT container_id FROM exp_containers
WHERE manufacturer_id = vr_dm.tc_id
AND batch_id = vr_dm.batch_id
AND exp_dea_group = vr_dm.EXP_DEA_GROUP
AND container_type_id = 1
AND parent_id IS NOT NULL
AND NVL(ship_via, 'F') = NVL(vr_dm.RETURN_VIA,'F')))
;
CURSOR mfr_risw_returns_cur IS
SELECT SUM(ol.extended_price) price
FROM exp_order_lines ol, exp_order_headers oh
WHERE oh.batch_id = vr_dm.batch_id
AND oh.order_header_id = ol.order_header_id
AND ol.return_waste_indate_flag = 'R'
AND ol.cap_line = 'Y'
AND ol.return_in_system_indicator = 'Y'
AND NVL(ol.cla_rx_code_drug_code, 'RX') IN
(SELECT dea_class_code FROM exp_dea_class WHERE
exp_dea_group = vr_dm.EXP_DEA_GROUP)
AND ol.manufacturer_name IN
(SELECT manufacturer_name FROM mfrs_in_debit_memo WHERE
exp_dm_number = vr_dm.exp_dm_number) ;
CURSOR retDepot_phy_returns_cur IS
SELECT SUM(extended_price) price
FROM exp_order_lines ol
WHERE order_line_id IN
(SELECT order_line_id FROM exp_contents_of_bag WHERE
container_id IN
(SELECT container_id FROM exp_containers
WHERE manufacturer_id = vr_dm.tc_id
AND batch_id = vr_dm.batch_id
AND exp_dea_group = vr_dm.exp_dea_group
AND container_type_id = 1
AND parent_id IS NOT NULL
AND NVL(ship_via, 'F') = NVL(vr_dm.RETURN_VIA, 'F')))
AND manufacturer_name IN (SELECT manufacturer_name FROM
mfrs_in_debit_memo mfrs --, exp_trading_community tc
WHERE mfrs.exp_dm_number =
vr_dm.exp_dm_number
AND parent_mfr_id = P_MFR_ID);
CURSOR retDepot_risw_returns_cur IS
SELECT SUM(ol.extended_price) price
FROM exp_order_lines ol, exp_order_headers oh
WHERE oh.batch_id = vr_dm.batch_id
AND oh.order_header_id = ol.order_header_id
AND ol.return_waste_indate_flag = 'R'
AND ol.cap_line = 'Y'
AND ol.return_in_system_indicator = 'Y'
AND ol.wholesaler_fax_unipak_flag = (SELECT tc_initial FROM
exp_trading_community
WHERE tc_id = vr_dm.tc_id)
AND NVL(ol.cla_rx_code_drug_code, 'RX') IN
(SELECT dea_class_code FROM exp_dea_class WHERE
exp_dea_group = vr_dm.exp_dea_group)
AND ol.manufacturer_name IN (SELECT manufacturer_name FROM
mfrs_in_debit_memo
WHERE exp_dm_number =
vr_dm.exp_dm_number
AND parent_mfr_id = P_MFR_ID);
BEGIN
SELECT * INTO vr_dm FROM EXP_DEBIT_MEMO WHERE
EXP_DM_NUMBER=P_DM_NUMBER;
SELECT * INTO vr_eb FROM EXP_BATCH WHERE BATCH_ID=vr_dm.BATCH_ID;
IF vr_dm.BATCH_ID IS NOT NULL THEN -- CAP
IF NVL(vr_dm.DM_FOR_RISW_FLAG,'N') = 'N' AND vr_dm.TC_TYPE_ID =
1 THEN
FOR mfr_phy_returns_rec IN mfr_phy_returns_cur LOOP
vn_amount:=mfr_phy_returns_rec.price;
END LOOP;
ELSIF NVL(vr_dm.DM_FOR_RISW_FLAG,'N') = 'Y' AND vr_dm.TC_TYPE_ID
= 1 THEN
FOR mfr_risw_returns_rec IN mfr_risw_returns_cur LOOP
vn_amount:=mfr_risw_returns_rec.price;
END LOOP;
ELSIF NVL(vr_dm.DM_FOR_RISW_FLAG,'N') = 'N' AND vr_dm.TC_TYPE_ID
= 6 THEN
FOR retDepot_phy_returns_rec IN retDepot_phy_returns_cur LOOP
vn_amount:=retDepot_phy_returns_rec.price;
END LOOP;
ELSIF NVL(vr_dm.DM_FOR_RISW_FLAG,'N') = 'Y' AND vr_dm.TC_TYPE_ID
= 6 THEN
FOR retDepot_risw_returns_rec IN retDepot_risw_returns_cur
LOOP
vn_amount:=retDepot_risw_returns_rec.price;
END LOOP;
END IF;
ELSE -- Non-CAP
null;
END IF;
return NVL(vn_amount,0);
thanks
Gints Plivna wrote:
> Sujatha wrote: > >Can you suggests something? > > Switching between SQL and PL/SQL generally is bad idea at least from > performance viewpoint. The best thing is to incorporate the logic into > the very sql statement. On the other hand just because your query > returns 1 row that really doesn't mean that function is called once, it > can be called zillion times and only later some other filters applied. > So check how many times your function is applied. Trace could be a tool > here. If you cannot incorporate function logic into the sql statement > then generally you'd like to apply function as late as possible after > all other filters are applied. > > Gints Plivna > http://www.gplivna.eu/Received on Thu Jul 13 2006 - 14:24:19 CDT
![]() |
![]() |