How to get rid of cursor loop to improve performance? - oracle

I have a function is like below, which has very bad performance, because of cursor loop. I need somebody help me get rid of the cursor and using one statement instead. Anybody can help will be greate appreciated!!
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;
The c_cur1 will return like :
patr_id
1001
1002
1003
1004
The c_cur2 will return a date like:
2001-jan-01 ( patr_id : 1001)
2002-jan-01 ( patr_id : 1002)
2003-jan-01 ( patr_id : 1003)
2004-jan-01 ( patr_id : 1004)
the final result v_rst will get the minimum date from (2001-jan-01, 2002-jan-01, 2003-jan-01, 2004-jan-01)
So, I need a way to get rid of the cursor loop (performance too bad) and using one statement get the final result.

Something like following may help you.
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;

Your query of c_cur1 seems to be incorrect. Its result doesn't depend on p_patr_id parameter.
The only place where p_patr_id is mentioned, is the following subquery:
(select pat.pat_id
from pat, pat_register patr
where patr.patr_id = p_patr_id)
The result of this subquery obviously doesn't depend on p_patr_id. :-)

Related

ORA-01427 Single-Row Subquery Returns More than One Row - how to resolve?

I've had this query running for over 2 years and just recently this began throwing the ORA-01427 single row sub-query returns multiple rows error. What's the best way to debug this when there are multiple sub-queries? Should I be adding a MAX statement to each subquery? I've tried switching some of the = operators to IN but that's not working and I'm not confident it would give me the correct results either.
Appreciate any insight or assistance this community can provide. I'm ripping my hair out working through this one!
SELECT
NVL(
(SELECT
'Y'
FROM
PER_ASSIGNMENT_SUPERVISORS_F
WHERE
MANAGER_ID = PAPF.PERSON_ID
AND MANAGER_TYPE ='LINE_MANAGER'
AND TRUNC(SYSDATE) BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
AND ROWNUM = 1),'N') MANAGER_FLAG,
PAAM.ASSIGNMENT_STATUS_TYPE,
PAAM.EMPLOYMENT_CATEGORY,
TO_CHAR(PPOS.DATE_START,'YYYY-MM-DD') AS HIRE_DATE,
PER_EXTRACT_UTILITY.GET_STANDARD_WORKING_HOURS(PAAM.ASSIGNMENT_ID,TRUNC(SYSDATE)) AS STANDARD_WORKING_HOURS,
TO_CHAR(PAAM.EFFECTIVE_START_DATE,'YYYY-MM-DD') AS EFFECTIVE_START_DATE,
(
SELECT
PJFVL.JOB_CODE
FROM
PER_ALL_ASSIGNMENTS_M PAAM1,
PER_JOBS_F_VL PJFVL
WHERE
PAAM1.PERSON_ID = PASF.MANAGER_ID
AND TRUNC(SYSDATE) BETWEEN PAAM1.EFFECTIVE_START_DATE AND PAAM1.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN PJFVL.EFFECTIVE_START_DATE AND PJFVL.EFFECTIVE_END_DATE
and PAAM1.ASSIGNMENT_STATUS_TYPE='ACTIVE'
AND PAAM1.ASSIGNMENT_TYPE = 'E'
AND PAAM1.effective_latest_change = 'Y'
AND PJFVL.JOB_ID = PAAM1.JOB_ID
)as Manager_job_code,
(
SELECT
HOIF.ORG_INFORMATION1
FROM
PER_ALL_ASSIGNMENTS_M PAAM2,
HR_ORGANIZATION_INFORMATION_F HOIF
WHERE
PAAM2.PERSON_ID = PASF.MANAGER_ID
AND HOIF.ORG_INFORMATION_CONTEXT = 'DEPT_DET'
and PAAM2.ASSIGNMENT_STATUS_TYPE='ACTIVE'
AND PAAM2.ASSIGNMENT_TYPE = 'E'
AND PAAM2.effective_latest_change = 'Y'
AND TRUNC(SYSDATE) BETWEEN PAAM2.EFFECTIVE_START_DATE AND PAAM2.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN HOIF.EFFECTIVE_START_DATE AND HOIF.EFFECTIVE_END_DATE
AND HOIF.ORGANIZATION_ID = PAAM2.ORGANIZATION_ID
) as Manager_dep_code,
(SELECT
COUNT(PPOS.PERIOD_OF_SERVICE_ID)
FROM
PER_PERIODS_OF_SERVICE PPOS
WHERE
1 = 1
AND PAAM.PERSON_ID = PPOS.PERSON_ID
) AS INACTIVE_WORKRELATIONSHIP,
PAPF.PERSON_NUMBER as SAMACCOUNTNAME,
(SELECT CSB.NAME FROM
CMP_SALARY CS,
CMP_SALARY_BASES CSB
WHERE
CS.ASSIGNMENT_ID = PAAM.ASSIGNMENT_ID
AND CS.SALARY_BASIS_ID = CSB.SALARY_BASIS_ID
and TRUNC(SYSDATE) BETWEEN CS.DATE_FROM AND CS.DATE_TO
) AS hourly_salary_Paid,
TO_CHAR(PP.DATE_OF_BIRTH,'YYYY-MM-DD') AS DOB,
PPNFV.LAST_NAME,
PPNFV.FIRST_NAME,
HLA.LOCATION_NAME as Location,
HLA.ADDRESS_LINE_1 AS LOC_ADDRESS_1,
HLA.ADDRESS_LINE_2 AS LOC_ADDRESS_2,
HLA.TOWN_OR_CITY AS City,
HLA.POSTAL_CODE AS ZIP_CODE,
HLA.REGION_2 AS STATE,
PPNFV.KNOWN_AS AS PREFERRED_NAME,
TRIM((PPNFV.KNOWN_AS||' '||PPNFV.LAST_NAME)) AS PREFERRED_NAME_LAST_NAME,
(SELECT
PPNFV.DISPLAY_NAME
FROM per_person_names_f_v PPNFV
WHERE 1 = 1
AND PPNFV.PERSON_ID = PASF.MANAGER_ID
AND PPNFV.NAME_TYPE='GLOBAL'
AND TRUNC(SYSDATE) BETWEEN PPNFV.EFFECTIVE_START_DATE AND PPNFV.EFFECTIVE_END_DATE
) AS MANAGER_NAME,
(SELECT
PAPF.PERSON_NUMBER
FROM PER_ALL_PEOPLE_F PAPF
WHERE PAPF.PERSON_ID = PASF.MANAGER_ID
AND TRUNC(SYSDATE) BETWEEN PAPF.EFFECTIVE_START_DATE AND PAPF.EFFECTIVE_END_DATE
) AS MANAGER_NUMBER,
HAOUFVL.NAME AS DEPARTMENT,
PAAM.ASSIGNMENT_NAME AS JOB_TILE,
PLE.NAME as Company,
PJLG.INFORMATION1 AS FLSA,
SUBSTR(PNI.NATIONAL_IDENTIFIER_NUMBER,-4) AS SSN_NUMBER,
PAAM.ASS_ATTRIBUTE1 as Officer_TITLE,
(
select
bu.name
from
hr_all_organization_units_f_vl bu
where 1 = 1
and paam.business_unit_id = bu.organization_id
and trunc(sysdate) between bu.effective_start_date and bu.effective_end_date
) as BUS_UNIT,
TO_CHAR (PPOS.ORIGINAL_DATE_OF_HIRE,'YYYY-MM-DD') AS ORIGINAL_DATE_OF_HIRE1,
(
CASE WHEN PPLF.SEX = 'F' THEN
'TRUE'
ELSE
'FALSE'
END
) AS GENDER,
(
CASE WHEN PJFFVL.JOB_FAMILY_NAME = 'Executive' THEN
'ELT'
ELSE
' '
END
) AS ELT_DESIGNATION,
HOIF.ORG_INFORMATION1 as DEPATMENT_CODE,
PJFV.JOB_CODE AS JOB_CODE,
PAF.ADDRESS_LINE_1 AS HOME_ADDRESS_LINE_1,
PAF.ADDRESS_LINE_2 AS HOME_ADDRESS_LINE_2,
PAF.TOWN_OR_CITY AS HOW_ADDRESS_CITY,
PAF.REGION_2 AS HOME_ADDRESS_STATE,
PAF.POSTAL_CODE AS HOME_ADRESS_ZIP_CODE,
PGFTL.NAME as Grade_level,
(SELECT
distinct (per_extract_utility.get_decoded_lookup('JOB_FUNCTION_CODE',PJF.JOB_FUNCTION_CODE))
FROM
PER_JOB_SECURED_LIST_V job WHERE TRUNC(SYSDATE) BETWEEN effective_start_date AND effective_end_date
) as JOB_FUNCTION,
pp.attribute1 as PER_NETWORKID,
(SELECT
PPNFV.attribute1
FROM PER_PERSONS PPNFV
WHERE 1 = 1
AND PPNFV.PERSON_ID = PASF.MANAGER_ID
) AS MANAGER_NETWORKID,
HOIF.ORG_INFORMATION2 AS REGION,
to_char(paam.ass_attribute_date1,'MM/DD/YYYY') as OfficerPromoDate
FROM
PER_ALL_ASSIGNMENTS_M PAAM,
PER_ASSIGNMENT_SUPERVISORS_F PASF,
PER_PERIODS_OF_SERVICE PPOS,
PER_ALL_PEOPLE_F PAPF,
PER_PERSONS PP,
per_person_names_f_v PPNFV,
HR_LOCATIONS_ALL HLA,
HR_ALL_ORGANIZATION_UNITS_F_VL HAOUFVL,
PER_JOB_LEG_F PJLG,
PER_NATIONAL_IDENTIFIERS PNI,
PER_PEOPLE_LEGISLATIVE_F PPLF,
PER_JOB_FAMILY_F_VL PJFFVL,
PER_JOBS_F_V PJFV,
HR_ORGANIZATION_INFORMATION_F HOIF,
PER_ADDRESSES_F PAF,
PER_PERSON_ADDR_USAGES_F PPAUF,
PER_GRADES_F_TL PGFTL,
PER_JOBS_F PJF,
PER_LEGAL_EMPLOYERS PLE,
HR_ALL_ORGANIZATION_UNITS_F HAOUF
WHERE
PAAM.ASSIGNMENT_STATUS_TYPE='ACTIVE'
AND PAAM.ASSIGNMENT_TYPE = 'E'
AND PAAM.effective_latest_change = 'Y'
AND PAAM.ASSIGNMENT_ID = PASF.ASSIGNMENT_ID(+)
AND PASF.MANAGER_TYPE (+) = 'LINE_MANAGER'
AND PNI.PERSON_ID(+) = PAAM.PERSON_ID
AND PAAM.PERSON_ID = PPLF.PERSON_ID(+)
and PJFV.JOB_FAMILY_ID= PJFFVL.JOB_FAMILY_ID(+)
AND PJFV.JOB_ID(+) = PAAM.JOB_ID
AND HOIF.ORGANIZATION_ID(+)= PAAM.ORGANIZATION_ID
AND HOIF.ORG_INFORMATION_CONTEXT(+) = 'DEPT_DETAILS'
AND PPAUF.PERSON_ID(+)= PAPF.PERSON_ID
AND PPAUF.ADDRESS_TYPE (+) = 'HOME'
AND PPAUF.ADDRESS_ID= PAF.ADDRESS_ID(+)
AND PGFTL.GRADE_ID(+)= PAAM.GRADE_ID
AND PJF.JOB_ID(+)= PAAM.JOB_ID
AND PJLG.INFORMATION_CATEGORY='HRX_US_JOBS'
and HAOUF.ORGANIZATION_ID(+)=PLE.ORGANIZATION_ID
and PAAM.LEGAL_ENTITY_ID=PLE.ORGANIZATION_ID
AND TRUNC(SYSDATE) BETWEEN PAAM.EFFECTIVE_START_DATE(+) AND PAAM.EFFECTIVE_END_DATE (+)
AND PAAM.PERIOD_OF_SERVICE_ID = PPOS.PERIOD_OF_SERVICE_ID
AND PAPF.PERSON_ID = PAAM.PERSON_ID
AND PP.PERSON_ID = PAAM.PERSON_ID
AND PPNFV.PERSON_ID = PAAM.PERSON_ID
AND HLA.LOCATION_ID(+) = PAAM.LOCATION_ID
AND PJLG.JOB_ID(+) = PAAM.JOB_ID
AND HAOUFVL.ORGANIZATION_ID(+) = PAAM.ORGANIZATION_ID
AND PPNFV.NAME_TYPE = 'GLOBAL'
AND TRUNC(SYSDATE) BETWEEN PPNFV.EFFECTIVE_START_DATE AND PPNFV.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN PAPF.EFFECTIVE_START_DATE AND PAPF.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN HAOUFVL.EFFECTIVE_START_DATE(+) AND HAOUFVL.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PPLF.EFFECTIVE_START_DATE(+) AND PPLF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PJFFVL.EFFECTIVE_START_DATE(+) AND PJFFVL.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PJFV.EFFECTIVE_START_DATE(+) AND PJFV.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN HOIF.EFFECTIVE_START_DATE(+) AND HOIF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PAF.EFFECTIVE_START_DATE(+) AND PAF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PPAUF.EFFECTIVE_START_DATE(+) AND PPAUF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PGFTL.EFFECTIVE_START_DATE(+) AND PGFTL.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PJF.EFFECTIVE_START_DATE(+) AND PJF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PLE.EFFECTIVE_START_DATE AND PLE.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN HAOUF.EFFECTIVE_START_DATE(+) AND HAOUF.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN HLA.EFFECTIVE_START_DATE(+) AND HLA.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PJLG.EFFECTIVE_START_DATE(+) AND PJLG.EFFECTIVE_END_DATE(+)
AND TRUNC(SYSDATE) BETWEEN PASF.EFFECTIVE_START_DATE(+) AND PASF.EFFECTIVE_END_DATE(+)
ORDER BY PAPF.PERSON_NUMBER
Run the query in a SQL client that will generate a more detailed error message. For example, the below code is run in SQL*Plus, which correctly indicates that the problem is with the subquery on line 3.
SQL> select
2 (select 1 from dual) this_will_work,
3 (select 1 from dba_objects) this_will_fail,
4 (select 1 from dual) this_will_work
5 from dual;
(select 1 from dba_objects) this_will_fail,
*
ERROR at line 3:
ORA-01427: single-row subquery returns more than one row

ORA-01427 Single row subquery return more than one row

I have the below query once I run it, it's exceeded successfully without error, but when I run it inside a procedure, I got the single error.
CREATE OR REPLACE PROCEDURE ABLEA_NEW.AB_VATFILE
IS
fHandle UTL_FILE.FILE_TYPE;
err varchar2(200);
v_str VARCHAR2(4000);
CURSOR VAT1 IS
SELECT (SELECT cif_no
FROM nbfc_customer_m
WHERE customerid = a.bpid) ||
(SELECT EXTRACT_ACCT(HOST_ACCT_INFO, 'SUFFIX')
FROM LEA_AGREEMENT_GROUPGL_MAP A, FA_ACCTCATG_M B
WHERE EXTRACT_ACCT(A.HOST_ACCT_INFO, 'ACCTCATG') = B.ACCTCATG
AND B.GROUPID = 'FA'
AND A.ACTIVE_FLAG = 'Y'
and AGREEMENTID = a.caseid)
"Account No",lpad(a.caseid,6,0) Loan_No
,
(SELECT AGREEMENTNO
FROM lea_agreement_dtl
WHERE AGREEMENTID = a.caseid)
AGREEMENTNO
,
LPAD(A.productid,3,0) Scheme_ID,
(SELECT rpad(schemedesc,35,' ')
FROM lea_scheme_m
WHERE schemeid = a.productid)
SchemeDesc,
to_char(a.advicedate,'ddmmyyyy') advicedate,
it_conv(a.adviceamt) adviceamt,
rpad(a.chargeid,6,' ')chargeid,
(SELECT rpad(chargedesc,35,' ')
FROM nbfc_charges_m
WHERE chargeid = a.chargeid)
"Charge Description",
IT_CONV(a.chargeamt)chargeamt,
(SELECT
decode(count(1),0,'N','Y')
FROM nbfc_pmnt_dtl y
WHERE a.txnadviceid = y.txnadviceid
AND a.status = 'A'
AND y.status IS NULL
--and TRUNC(y.pmntdate) between :p_datefrom and :p_dateto
AND a.tax_applicable = 'Y'
AND a.ptxnadviceid IS NULL)Paid,
LPAD(b.chargeid,6,0)
"VAT ChargeID",
(SELECT RPAD(chargedesc,35,' ')
FROM nbfc_charges_m
WHERE chargeid = b.chargeid)
"VAT Charge Description",
IT_CONV(b.chargeamt)
"VAT Amount"
FROM (SELECT *
FROM nbfc_txn_advice_dtl
WHERE status = 'A' AND tax_applicable = 'Y' AND ptxnadviceid IS NULL)
a,
(SELECT *
FROM nbfc_txn_advice_dtl
WHERE status = 'A' AND ptxnadviceid IS NOT NULL) b
WHERE a.txnadviceid = b.ptxnadviceid;
BEGIN
fHandle := UTL_FILE.FOPEN('UAEDB', 'VAT', 'W');
FOR I IN VAT1
LOOP
v_str:= null;
v_str:= I."Account No"||I.Loan_No||I.AGREEMENTNO || I.Scheme_ID ||I.SchemeDesc|| I.advicedate|| I.adviceamt|| I.chargeid||I."Charge Description"||I.chargeamt||I.Paid||
I."VAT ChargeID" ||I."VAT Charge Description"||I."VAT Amount";
UTL_FILE.PUTF(fHandle,v_str);
UTL_FILE.PUTF(fHandle, '\n');
END LOOP;
UTL_FILE.FCLOSE(fHandle);
END ;
/
How can I solve this?
Note: the query return mor than 10000 record.
comment or un-comment the "(select from )as ColumnAlias" query column one by one, you can find which sub query column return more than one row

I want to add a subquery with a date parameter to return a calculated value but my query is not working

I have a query that fetches data from oracle inventory and purchasing. Now I want to add a subquery from po_line_locations_all with a date parameter to return a calculated value as if the value lies in the subquery show it else display zero, But in my case the query shows nothing if subquery returns null.
I want to show the result of the main query even if subquery returns null.
SELECT distinct msib.segment1 Item_Code,
MSIB.inventory_item_id,
MSIB.organization_id ORG_ID,
msib.description Item_Description,
msib.primary_unit_of_measure UOM,
ph.attribute1 Item_Type,
SUM(plla.quantity) - SUM(plla.quantity_received) On_Order,
ph.currency_code currency,
max(pl.unit_price) FOB_Value_in_FCY,
max(ph.rate_date),
max(ph.rate) forex_rate,
(
SELECT SUM (moq.transaction_quantity)
FROM mtl_system_items_b msi, mtl_onhand_quantities moq
WHERE moq.organization_id(+) = msi.organization_id
AND moq.inventory_item_id(+) = msi.inventory_item_id
and moq.ORGANIZATION_ID =MSIB.organization_id
and msi.inventory_item_id = MSIB.inventory_item_id
GROUP BY msi.segment1, msi.organization_id
) CURR_STOCK,
(
SELECT NVL(ABS(sum(mtmt.transaction_quantity)),0) from MTL_MATERIAL_TRANSACTIONS mtmt
WHERE 1=1
AND mtmt.inventory_item_id = MSIB.inventory_item_id --4018
AND mtmt.organization_id = MSIB.organization_id--499
and mtmt.TRANSACTION_ACTION_ID NOT IN (24, 30)
AND to_date(mtmt.transaction_date) >= to_date(&Roll_back_date,'DD-MON-RRRR')
)RB_TRANSACTIONS,
(
select ABS(SUM(mmt.transaction_quantity))
from MTL_MATERIAL_TRANSACTIONS mmt
where mmt.TRANSACTION_ACTION_ID NOT IN (24, 30)
and (mmt.ORGANIZATION_ID = MSIB.organization_id --499--579
)
and (mmt.INVENTORY_ITEM_ID = MSIB.inventory_item_id --4128 --4165
and mmt.TRANSACTION_TYPE_ID in (33, 52)
)
and (mmt.transaction_date between
to_date(add_months(&CONS_f_DATE, -12),'DD-MON-YYYY')
AND to_date(&CONS_f_DATE, 'DD-MON-YYYY')
)
AND (mmt.parent_transaction_id IS NULL)
) annual_Consumption,
(
select ABS(SUM(mmt.transaction_quantity) / 4)
FROM MTL_MATERIAL_TRANSACTIONS mmt
WHERE mmt.TRANSACTION_ACTION_ID NOT IN (24, 30)
and (mmt.ORGANIZATION_ID = MSIB.organization_id --499--579
)
and (mmt.INVENTORY_ITEM_ID = MSIB.inventory_item_id --4128 --4165
AND mmt.TRANSACTION_TYPE_ID in (33, 52)
)
and (mmt.transaction_date between
to_date(add_months(&CONS_f_DATE, -12),
'DD-MON-YYYY') AND
to_date(&CONS_f_DATE, 'DD-MON-YYYY'))
AND (mmt.parent_transaction_id IS NULL)
) months_Consumption,
(
select ABS((SUM(mmt.transaction_quantity) / 4) / 3)
FROM MTL_MATERIAL_TRANSACTIONS mmt
WHERE mmt.TRANSACTION_ACTION_ID NOT IN (24, 30)
and (mmt.ORGANIZATION_ID = MSIB.organization_id --499--579
)
and (mmt.INVENTORY_ITEM_ID = MSIB.inventory_item_id --4128 --4165
AND mmt.TRANSACTION_TYPE_ID in (33, 52))
and (mmt.transaction_date between
to_date(add_months(&CONS_f_DATE, -12),
'DD-MON-YYYY') AND
to_date(&CONS_f_DATE, 'DD-MON-YYYY'))
AND (mmt.parent_transaction_id IS NULL)
) monthly_Average,
(
select MATERIAL_COST
FROM CST_ITEM_COST_TYPE_V vw
WHERE vw.organization_id = MSIB.organization_id
AND - 1 = -1
and (vw.INVENTORY_ITEM_ID = MSIB.inventory_item_id)
) Unit_Cost, --new
sum(quan.t_quantity) - sum(r_quantity) finala
FROM mtl_system_items_b MSIB,
PO_HEADERS_ALL ph,
Po_Lines_All pl,
PO_LINE_LOCATIONS_ALL PLLA,
-------------------SUBQUERY---------------------------------------
(select nvl(sum(subplla.quantity),0) t_quantity, nvl(sum(subplla.quantity_received),0) r_quantity ,subpl.item_id
from po_headers_all subph,
po_lines_all subpl,
po_line_locations_all subplla
where subph.po_header_id = subpl.po_header_id
and subplla.po_header_id = subph.po_header_id
and subpl.po_line_id = subplla.po_line_id
and subplla.org_id = subpl.org_id
and to_date(subplla.creation_date) >= to_date(&Roll_back_date,'DD-MON-RRRR')
group by subph.attribute1, subph.currency_code, subpl.item_id
) quan
-------------------SUBQUERY---------------------------------------
WHERE 1=1
and ph.po_header_id = pl.po_header_id
and msib.inventory_item_id (+) = pl.item_id
and pl.item_id (+) = quan.item_id
and plla.po_header_id = ph.po_header_id
and pl.po_line_id = plla.po_line_id
and plla.org_id = pl.org_id
and msib.organization_id in
(select haou.organization_id
from hr_organization_information hoi,
hr_all_organization_units haou
where haou.organization_id = hoi.organization_id
and hoi.org_information1 = 'INV'
and hoi.org_information2 = 'Y'
and haou.name like '%HEIS%')
and MSIB.Inventory_Item_Id=NVL(&ITEM,MSIB.Inventory_Item_Id)
and MSIB.organization_id = nvl(&P_ORGI, MSIB.organization_id)
AND to_date(plla.creation_date) BETWEEN
to_date(add_months(&Roll_back_date, -12),'DD-MON-YYYY') AND
to_date(&Roll_back_date,'DD-MON-YYYY')
GROUP BY msib.segment1,
MSIB.inventory_item_id,
msib.description,
MSIB.organization_id,
msib.primary_unit_of_measure,
ph.attribute1,
ph.currency_code
My guess is that your problem is simply using old-syntax joins instead of something that has been around for a really long time.
SELECT DISTINCT msib.segment1 Item_Code,
MSIB.inventory_item_id,
MSIB.organization_id ORG_ID,
msib.description Item_Description,
msib.primary_unit_of_measure UOM,
ph.attribute1 Item_Type,
SUM(plla.quantity) - SUM(plla.quantity_received) On_Order,
ph.currency_code currency,
max(pl.unit_price) FOB_Value_in_FCY,
max(ph.rate_date),
max(ph.rate) forex_rate,
(
SELECT SUM(moq.transaction_quantity)
FROM mtl_system_items_b msi
RIGHT JOIN mtl_onhand_quantities moq ON moq.organization_id = msi.organization_id
AND moq.inventory_item_id = msi.inventory_item_id
WHERE moq.ORGANIZATION_ID = MSIB.organization_id
AND msi.inventory_item_id = MSIB.inventory_item_id
GROUP BY msi.segment1,
msi.organization_id
) CURR_STOCK,
(
SELECT NVL(ABS(sum(mtmt.transaction_quantity)), 0)
FROM MTL_MATERIAL_TRANSACTIONS mtmt
WHERE 1 = 1
AND mtmt.inventory_item_id = MSIB.inventory_item_id --4018
AND mtmt.organization_id = MSIB.organization_id --499
AND mtmt.TRANSACTION_ACTION_ID NOT IN (24,30)
AND to_date(mtmt.transaction_date) >= to_date(&Roll_back_date, 'DD-MON-RRRR')
) RB_TRANSACTIONS,
mmt.annual_Consumption annual_Consumption,
mmt.annual_Consumption / 4 months_Consumption,
mmt.annual_Consumption / 12 monthly_Average,
(
SELECT MATERIAL_COST
FROM CST_ITEM_COST_TYPE_V vw
WHERE vw.organization_id = MSIB.organization_id
AND vw.INVENTORY_ITEM_ID = MSIB.inventory_item_id
) Unit_Cost, --new
sum(quan.t_quantity) - sum(r_quantity) finala
FROM mtl_system_items_b MSIB
LEFT JOIN PO_HEADERS_ALL ph ON msib.inventory_item_id = pl.item_id
INNER JOIN Po_Lines_All pl ON ph.po_header_id = pl.po_header_id
INNER JOIN PO_LINE_LOCATIONS_ALL PLLA ON plla.po_header_id = ph.po_header_id AND pl.po_line_id = plla.po_line_id AND plla.org_id = pl.org_id
LEFT JOIN
-------------------SUBQUERY---------------------------------------
(
SELECT nvl(sum(subplla.quantity), 0) t_quantity,
nvl(sum(subplla.quantity_received), 0) r_quantity,
subpl.item_id
FROM po_headers_all subph
INNER JOIN po_lines_all subpl ON subph.po_header_id = subpl.po_header_id
INNER JOIN po_line_locations_all subplla ON subplla.po_header_id = subph.po_header_id
AND subpl.po_line_id = subplla.po_line_id
AND subplla.org_id = subpl.org_id
WHERE to_date(subplla.creation_date) >= to_date(&Roll_back_date, 'DD-MON-RRRR')
GROUP BY subph.attribute1,
subph.currency_code,
subpl.item_id
) quan ON pl.item_id = quan.item_id
-------------------SUBQUERY---------------------------------------
LEFT JOIN (
SELECT mmt.ORGANIZATION_ID,
mmt.INVENTORY_ITEM_ID,
ABS(SUM(mmt.transaction_quantity)) AS annual_Consumption
FROM MTL_MATERIAL_TRANSACTIONS mmt
WHERE mmt.TRANSACTION_ACTION_ID NOT IN (24,30)
AND mmt.TRANSACTION_TYPE_ID IN (33,52)
AND mmt.transaction_date BETWEEN to_date(add_months(&CONS_f_DATE, - 12), 'DD-MON-YYYY')
AND to_date(&CONS_f_DATE, 'DD-MON-YYYY')
AND mmt.parent_transaction_id IS NULL
) mmt ON mmt.ORGANIZATION_ID = MSIB.organization_id --499--579
AND mmt.INVENTORY_ITEM_ID = MSIB.inventory_item_id --4128 --4165
WHERE msib.organization_id IN (
SELECT haou.organization_id
FROM hr_organization_information hoi
JOIN hr_all_organization_units haou ON haou.organization_id = hoi.organization_id
WHERE hoi.org_information1 = 'INV'
AND hoi.org_information2 = 'Y'
AND haou.name LIKE '%HEIS%'
)
AND MSIB.Inventory_Item_Id = NVL(&ITEM, MSIB.Inventory_Item_Id)
AND MSIB.organization_id = nvl(&P_ORGI, MSIB.organization_id)
AND to_date(plla.creation_date) BETWEEN to_date(add_months(&Roll_back_date, - 12), 'DD-MON-YYYY')
AND to_date(&Roll_back_date, 'DD-MON-YYYY')
GROUP BY msib.segment1,
MSIB.inventory_item_id,
msib.description,
MSIB.organization_id,
msib.primary_unit_of_measure,
ph.attribute1,
ph.currency_code;
Here is the query in its simplest form, The main query is working good without the subquery. But when subquery returns null (i.e. no output in the date range) the whole query returns nothing. I want it to display results regardless the subquery results. My guess is something is wrong with the JOIN –
SELECT distinct msib.segment1 Item_Code,
MSIB.inventory_item_id,
MSIB.organization_id ORG_ID,
msib.description Item_Description,
msib.primary_unit_of_measure UOM,
ph.attribute1 Item_Type,
ph.currency_code currency,
max(pl.unit_price) FOB_Value_in_FCY,
max(ph.rate_date),
max(ph.rate) forex_rate,
sum(quan.t_quantity) - sum(r_quantity) finala
FROM mtl_system_items_b MSIB,
PO_HEADERS_ALL ph,
Po_Lines_All pl,
PO_LINE_LOCATIONS_ALL PLLA,
------------SUBQUERY-------------------------------
(select nvl(sum(subplla.quantity),0) t_quantity, nvl(sum(subplla.quantity_received),0) r_quantity ,subpl.item_id
from po_headers_all subph,
po_lines_all subpl,
po_line_locations_all subplla
where subph.po_header_id = subpl.po_header_id
and subplla.po_header_id = subph.po_header_id
and subpl.po_line_id = subplla.po_line_id
and subplla.org_id = subpl.org_id
and to_date(subplla.creation_date) >= to_date(&Roll_back_date,'DD-MON-RRRR')
group by subph.attribute1, subph.currency_code, subpl.item_id
) quan
------------SUBQUERY-------------------------------
WHERE 1=1
and ph.po_header_id = pl.po_header_id
and msib.inventory_item_id (+) = pl.item_id
-----------------joining subquery-------------------
and pl.item_id (+) = quan.item_id
-----------------joining subquery-------------------
and plla.po_header_id = ph.po_header_id
and pl.po_line_id = plla.po_line_id
and plla.org_id = pl.org_id
and msib.organization_id in
(select haou.organization_id
from hr_organization_information hoi,
hr_all_organization_units haou
where haou.organization_id = hoi.organization_id
and hoi.org_information1 = 'INV'
and hoi.org_information2 = 'Y'
and haou.name like '%HEIS%')
and MSIB.Inventory_Item_Id=NVL(&ITEM,MSIB.Inventory_Item_Id)
and MSIB.organization_id = nvl(&P_ORGI, MSIB.organization_id)
AND to_date(plla.creation_date) BETWEEN
to_date(add_months(&Roll_back_date, -12),'DD-MON-YYYY') AND
to_date(&Roll_back_date,'DD-MON-YYYY')
GROUP BY msib.segment1,
MSIB.inventory_item_id,
msib.description,
MSIB.organization_id,
msib.primary_unit_of_measure,
ph.attribute1,
ph.currency_code

Add IF ELSE Condition in PL SQL stored procedure

I have a scenario where I want to add an IF ELSE condition in my below procedure:
I tried like below but it is not getting compiled
PROCEDURE VSAT_EXCEL_REPORT
(
P_R4GSTATE IN NVARCHAR2,
TBLDATA OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN TBLDATA FOR
IF P_R4GSTATE = "ALL"
THEN
SELECT ENB.SAP_ID AS SAP_ID,CAND.CANDIDATEID AS CANDIDATE_ID,ENB.R4G_STATE AS STATE,ENB.SITE_TYPE AS SITE_TYPE,CAND.SITENAME AS SITE_NAME
,ENB.SITEID AS SITEID,ENB.PRIORITY_SITE AS PRIORITYSITE,ENB.CIRCLE AS CIRCLE,
DECODE (VTS.STATUS_NAME, null, 'Fill VSAT form', VTS.STATUS_NAME) AS STATUS,
ENB.LATITUDE
,ENB.LONGITUDE
,VT.SITE_DETAILS_TECHNOLOGY
,VT.SITE_DETAILS_MOUNT_TYPE
,VT.SITE_DETAILS_ANTENNA_SIZE
,VT.SITE_DETAILS_AMSL
,VT.SITE_DETAILS_PLATFORM_REQUIRED
,VT.SITE_DETAILS_PLATFORM_HEIGHT
,VT.SITE_DETAILS_ROOFTOP_SITE
,VT.SITE_DETAILS_NOOFLOORS
,VT.SITE_DETAILS_ADD_ROOFTOP_SITE
,VT.SITE_DETAILS_STRUCTURAL_STAB
,VT.SITE_DETAILS_HEIGHT_OF_ANTENNA
,VT.SITE_DETAILS_SATELLITE_BAND
,VT.ANTENNA_DISTANCE_NEAR_AIRPORT
,VT.ANTENNA_AIRPORT_NAME
,VT.GSAT_LOS_16_55E
,VT.GSAT_LOS_18_74E
,VT.GSAT_LOS_12_83E
FROM R4G_OSP.ENODEB ENB
INNER JOIN R4G_OSP.CANDIDATE CAND ON ENB.SAP_ID = CAND.SAP_ID
LEFT JOIN TBL_VSAT_MST_DETAIL VT ON ENB.SAP_ID = VT.SAP_ID
LEFT JOIN TBL_VSAT_STATUS_MST VTS ON VT.STATUS_ID = VTS.STATUS_ID
WHERE ENB.SCOPE = 'EnodeB-Connected_MW'
AND ENB.SITEBACKHAUL = 'MW'
AND CAND.STATUS = 'Fill Vendor Survey Form'
AND UPPER(STATE) IN
(SELECT REGEXP_SUBSTR(UPPER(P_R4GSTATE),'[^,]+', 1, LEVEL) AS RFIELDS FROM DUAL
CONNECT BY REGEXP_SUBSTR(UPPER(P_R4GSTATE), '[^,]+', 1, LEVEL) IS NOT NULL);
ELSE
--Some condtion
END VSAT_EXCEL_REPORT;
I think it should be image like this:
procedure VSAT_EXCEL_REPORT
(
P_R4GSTATE in nvarchar2,
TBLDATA out sys_refcursor
) as
begin
if P_R4GSTATE = 'ALL' then
open TBLDATA for
select ENB.SAP_ID as SAP_ID
,CAND.CANDIDATEID as CANDIDATE_ID
,ENB.R4G_STATE as STATE
,ENB.SITE_TYPE as SITE_TYPE
,CAND.SITENAME as SITE_NAME
,ENB.SITEID as SITEID
,ENB.PRIORITY_SITE as PRIORITYSITE
,ENB.CIRCLE as CIRCLE
,DECODE(VTS.STATUS_NAME
,null
,'Fill VSAT form'
,VTS.STATUS_NAME) as STATUS
,ENB.LATITUDE
,ENB.LONGITUDE
,VT.SITE_DETAILS_TECHNOLOGY
,VT.SITE_DETAILS_MOUNT_TYPE
,VT.SITE_DETAILS_ANTENNA_SIZE
,VT.SITE_DETAILS_AMSL
,VT.SITE_DETAILS_PLATFORM_REQUIRED
,VT.SITE_DETAILS_PLATFORM_HEIGHT
,VT.SITE_DETAILS_ROOFTOP_SITE
,VT.SITE_DETAILS_NOOFLOORS
,VT.SITE_DETAILS_ADD_ROOFTOP_SITE
,VT.SITE_DETAILS_STRUCTURAL_STAB
,VT.SITE_DETAILS_HEIGHT_OF_ANTENNA
,VT.SITE_DETAILS_SATELLITE_BAND
,VT.ANTENNA_DISTANCE_NEAR_AIRPORT
,VT.ANTENNA_AIRPORT_NAME
,VT.GSAT_LOS_16_55E
,VT.GSAT_LOS_18_74E
,VT.GSAT_LOS_12_83E
from R4G_OSP.ENODEB ENB
inner join R4G_OSP.CANDIDATE CAND
on ENB.SAP_ID = CAND.SAP_ID
left join TBL_VSAT_MST_DETAIL VT
on ENB.SAP_ID = VT.SAP_ID
left join TBL_VSAT_STATUS_MST VTS
on VT.STATUS_ID = VTS.STATUS_ID
where ENB.SCOPE = 'EnodeB-Connected_MW'
and ENB.SITEBACKHAUL = 'MW'
and CAND.STATUS = 'Fill Vendor Survey Form'
and
UPPER(STATE) in
(select REGEXP_SUBSTR(UPPER(P_R4GSTATE), '[^,]+', 1, level) as RFIELDS
from DUAL
connect by REGEXP_SUBSTR(UPPER(P_R4GSTATE), '[^,]+', 1, level) is not null);
else
open TBLDATA for
select * from dual;
end if;
end VSAT_EXCEL_REPORT;

I have an ORA-06533 error in a select clausule

I'm trying to do a select and I get an ORA-06533 subcript beyond count.
I don't understand why is this error because there are no subscripts in the select.
I post the relevant code:
TYPE Item IS RECORD (
entity number,
period number,
value NUMBER);
TYPE ItemSet IS TABLE OF Item;
modelo_pd ItemSet;
select id_scenario into sid from sae_lc_scen_var where us_type = num and type = 0 and id_segment = pid;
str := 'select distinct bd.entity_id, v.period_id, v.number_attribute_46 pd_pit
from sae_scenario s, sae_baseline b, sae_baseline_data bd, sae_entity e, v_sae_scenario_data v
where s.id = ' || sid || ' and b.scenario_type = s.scenario_type and b.id = bd.baseline_id
and bd.entity_id = e.id and b.id = s.baseline_id and v.scenario_id = s.id and v.baseline_id = b.id
and e.string_attribute_1 = ''' || t.name || ''' and v.e_string_attribute_1 = e.string_attribute_1';
execute immediate str bulk collect into modelo_pd;
The parameters for the query are from two other queries:
select id_scenario into sid from sae_lc_scen_var where us_type = num and type = 0 and id_segment = pid;
and the loop:
for t in (select v.id_segment, s.name, v.value expert, v.value3 selection, v.value2 correction from sae_lc_scen_var v, sae_lc_segments s
where v.us_type = 1 and v.type = 0
and s.id = v.id_segment and v.value <> 0)
The error raises in the dynamic select. That is in execute immediate str bulk collect into modelo_pd;
Any clue?
The full thing:
num := get_constant('US_TYPE_EAD_AGGREGATE');
for t in (select v.id_segment, s.name, v.value expert, v.value3 selection, v.value2 correction from sae_lc_scen_var v, sae_lc_segments s
where v.us_type = 1 and v.type = 0
and s.id = v.id_segment and v.value <> 0)
loop
-- value3: 0=Model, 1=Proxy VMG, 2=Expert, 3=PD_TTC
num := get_constant('US_TYPE_LGD_CALC_METHOD');
if t.selection = 0 then
num := get_constant('US_TYPE_MODELOS_PD');
select id_scenario into sid from sae_lc_scen_var where us_type = num and type = 0 and id_segment = pid;
str := 'select distinct bd.entity_id, v.period_id, v.number_attribute_46 pd_pit
from sae_scenario s, sae_baseline b, sae_baseline_data bd, sae_entity e, v_sae_scenario_data v
where s.id = ' || sid || ' and b.scenario_type = s.scenario_type and b.id = bd.baseline_id
and bd.entity_id = e.id and b.id = s.baseline_id and v.scenario_id = s.id and v.baseline_id = b.id
and e.string_attribute_1 = ''' || t.name || ''' and v.e_string_attribute_1 = e.string_attribute_1';
execute immediate str bulk collect into modelo_pd;
I've found the source of the error.
There is no rows for that select so when I use modelo_pd it gives that error.
What is unclear for me is why it is giving the line number way before the subscript is used.

Resources