How to insert rows using cursor in Oracle 11g - oracle
I am trying to write a function in oracle which will use cursor to insert data in one of the table. We need select query to pick the data which needs to be inserted. This is the first cursor I am writing and it turned to be too complex.
My cursor is as below:
/* Formatted on 11/5/2011 11:26:57 AM (QP5 v5.149.1003.31008) */
DECLARE
CURSOR csgetpgmecultstrecrefrs (
update_date DATE,
sequence_type VARCHAR2,
pip_number VARCHAR2,
startfrom INT,
endon INT)
IS
SELECT /*+first_rows(25) parallel (PE,20) */
pecu.component,
pecu.component_serial_no,
TO_DATE ('11/03/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS')
date_received,
TO_DATE ('11/03/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS')
date_programmed,
pecu.date_requested,
pecu.component_model_no,
pecu.product_type,
pecu.product_model_no,
pecu.product_serial_no,
pecu.factory_source,
pecu.programming_organization,
pecu.programming_site,
pecu.program_version,
pecu.ecu_serial_no,
pecu.ecu_part_no,
pecu.ecu_level,
pecu.software_assembly_id,
jdcp_pip_swa.pip_version software_assembly_id_upgrade,
TO_DATE ('11/03/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS')
software_upgrade_date,
jdcp_pip_details.released_by software_upgraded_by,
pecu.power_bump,
pecu.fuel_system_part_no,
pecu.fuel_pump_serial_no,
pecu.rack_slope,
pecu.off_set,
pecu.ecu_hours,
pecu.cal_file,
pecu.ecu_boot_block_part_no,
jdcp_pip_details.released_by user_id,
pecu.performance_option_part_no,
pecu.vehicle_option_part_no,
'PIP' sequence_type,
pecu.flex_power_part_no,
pecu.performance_option_cd,
pecu.vehicle_option_cd,
pecu.lineage,
pecu.replaced_by_esn,
pecu.replaces_esn,
pecu.esn_copied_from,
pecu.payload_seq_no,
pecu.vehicle_system_id,
pecu.user_account,
pecu.ecu_opcode_part_no,
pecu.opcode_compat_code,
pecu.marked_qa
FROM ( ( jdcp_pip_details
INNER JOIN
jdcp_pip_pin_assc
ON jdcp_pip_details.pip_number =
jdcp_pip_pin_assc.pip_number)
INNER JOIN
jdcp_pip_swa
ON jdcp_pip_details.pip_swa_id = jdcp_pip_swa.pip_swa_id)
INNER JOIN
( (SELECT pe.component,
pe.component_serial_no,
pe.display_serial_no_13,
pe.display_serial_no_17,
pe.date_requested,
pe.component_model_no,
pe.product_type,
pe.product_model_no,
pe.product_serial_no,
pe.factory_source,
pe.programming_organization,
pe.programming_site,
pe.program_version,
pe.ecu_serial_no,
pe.ecu_part_no,
pe.ecu_level,
pe.software_assembly_id,
pe.power_bump,
pe.fuel_system_part_no,
pe.fuel_pump_serial_no,
pe.rack_slope,
pe.off_set,
pe.ecu_hours,
pe.cal_file,
pe.ecu_boot_block_part_no,
pe.performance_option_part_no,
pe.vehicle_option_part_no,
pe.flex_power_part_no,
pe.performance_option_cd,
pe.vehicle_option_cd,
pe.lineage,
pe.replaced_by_esn,
pe.replaces_esn,
pe.esn_copied_from,
pe.payload_seq_no,
pe.vehicle_system_id,
pe.user_account,
pe.ecu_opcode_part_no,
pe.opcode_compat_code,
pe.marked_qa
FROM programmed_ecu_13_17_map_view pe
WHERE pe.date_received =
(SELECT /*+ INDEX_DESC(PEDR PROGRAMMED_ECU_INDEX8) */
pedr.date_received AS date_received
FROM programmed_ecu pedr
WHERE pedr.component_serial_no =
pe.component_serial_no
AND pedr.component = pe.component
AND (pedr.date_programmed) =
(SELECT /*+ INDEX_DESC(PEDP PROGRAMMED_ECU_INDEX8) */
pedp.date_programmed
FROM programmed_ecu pedp
WHERE pedp.
component_serial_no =
pedr.
component_serial_no
AND pedp.component =
pedr.component
AND ROWNUM = 1)
AND ROWNUM = 1)) pecu
INNER JOIN
software_assembly_id
ON pecu.vehicle_system_id =
software_assembly_id.vehicle_system_id)
ON (pecu.component = jdcp_pip_pin_assc.controller_short_name)
AND (jdcp_pip_swa.pip_version =
software_assembly_id.software_assembly_id)
AND (pecu.component =
software_assembly_id.controller_short_name)
WHERE (pecu.display_serial_no_13 = jdcp_pip_pin_assc.pin_number
OR pecu.display_serial_no_17 = jdcp_pip_pin_assc.pin_number)
AND pecu.software_assembly_id <> jdcp_pip_swa.pip_version
AND jdcp_pip_details.pip_number = 'TEST_FWD_ASSC'
AND jdcp_pip_pin_assc.status_cd NOT IN
('UC', 'SU', 'FA', 'RP', 'EC')
AND jdcp_pip_pin_assc.forward_associated = 'N'
AND ROWNUM BETWEEN 1 AND 25;
rc csgetpgmecultstrecrefrs%ROWTYPE;
BEGIN
OPEN csgetpgmecultstrecrefrs (update_date date,
sequence_type varchar2,
pip_number varchar2,
startfrom int,
endon int);
LOOP
FETCH csgetpgmecultstrecrefrs BULK COLLECT INTO rc;
EXIT WHEN csgetpgmecultstrecrefrs%NOTFOUND;
INSERT
INTO programmed_ecu (component,
component_serial_no,
date_received,
date_programmed,
date_requested,
component_model_no,
product_type,
product_model_no,
product_serial_no,
factory_source,
programming_organization,
programming_site,
program_version,
ecu_serial_no,
ecu_part_no,
ecu_level,
software_assembly_id,
software_assembly_id_upgrade,
software_upgrade_date,
software_upgraded_by,
power_bump,
fuel_system_part_no,
fuel_pump_serial_no,
rack_slope,
off_set,
ecu_hours,
cal_file,
ecu_boot_block_part_no,
user_id,
performance_option_part_no,
vehicle_option_part_no,
sequence_type,
flex_power_part_no,
performance_option_cd,
vehicle_option_cd,
lineage,
replaced_by_esn,
replaces_esn,
esn_copied_from,
payload_seq_no,
vehicle_system_id,
user_account,
ecu_opcode_part_no,
opcode_compat_code,
marked_qa
)
VALUES (
rc.component,
rc.component_serial_no,
rc.date_received,
rc.date_programmed,
rc.date_requested,
rc.component_model_no,
rc.product_type,
rc.product_model_no,
rc.product_serial_no,
rc.factory_source,
rc.programming_organization,
rc.programming_site,
rc.program_version,
rc.ecu_serial_no,
rc.ecu_part_no,
rc.ecu_level,
rc.software_assembly_id,
rc.software_assembly_id_upgrade,
rc.software_upgrade_date,
rc.software_upgraded_by,
rc.power_bump,
rc.fuel_system_part_no,
rc.fuel_pump_serial_no,
rc.rack_slope,
rc.off_set,
rc.ecu_hours,
rc.cal_file,
rc.ecu_boot_block_part_no,
rc.user_id,
rc.performance_option_part_no,
rc.vehicle_option_part_no,
rc.sequence_type,
rc.flex_power_part_no,
rc.performance_option_cd,
rc.vehicle_option_cd,
rc.lineage,
rc.replaced_by_esn,
rc.replaces_esn,
rc.esn_copied_from,
rc.payload_seq_no,
rc.vehicle_system_id,
rc.user_account,
rc.ecu_opcode_part_no,
rc.opcode_compat_code,
rc.marked_qa);
END LOOP;
COMMIT;
END;
Any help is appreciated. Thanks in advance !!!
Error message I am getting is:
Error at line 2
ORA-06550: line 147, column 44:
PLS-00103: Encountered the symbol "DATE" when expecting one of the following:
. ( ) , * # % & | = - + < / > at in is mod remainder not
range rem => .. <> or != or ~= >= <= <>
and or like LIKE2_ LIKE4_ LIKEC_ as between from using ||
multiset member SUBMULTISET_
ORA-06550: line 151, column 21:
PLS-00103: Encountered the symbol ")" when expecting one of the following:
, from into bulk
ORA-06550: line 254, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
Script Terminated on line 2."
The declaration of your cursor is incorrect. A cursor is not declared using data types, you need to remove the whole part between the brackets. The data types for each column are determined by the columns returned by the SELECT statement:
CURSOR csgetpgmecultstrecrefrs
IS
SELECT .....
See the examples in the manual for details:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/sqloperations.htm#sthref1296
Related
Function retuning Sys Refcursor
How to call a function returning sys refcursor in select statement. I have created a function like this and I want to call in the select statement returning both values coming from function. So I used in the query like this, but it is returning cursor in place of column values. Function HCLT_GET_TASK_DATES(i_ownerid IN NUMBER, i_itemid IN NUMBER) RETURN SYS_REFCURSOR IS o_DATACUR SYS_REFCURSOR; begin open o_DATACUR for select nvl(TO_CHAR(min(pref_start), 'DD-MON-YYYY'), '') AS MIN_DATE, nvl(TO_CHAR(max(pref_finish), 'DD-MON-YYYY'), '') AS MAX_DATE from autoplanallocation WHERE project_id = i_ownerid AND task_id = i_itemid; RETURN o_DATACUR; END; / SELECT HCLT_GET_TASK_DATES(267157, 15334208), tv.taskid, tv.wbs_code AS wbscode, tv.taskcode, tv.act_name, ltrim(regexp_replace(tv.stageactorlovs, '[^#]*#(\d+?),', ',\1'), ',') as stageactorlovs, tv.createdat, tv.pushedtoTaskModule, tv.OVERALLSTATUS AS overallstatus1, tv.ACTIVITY_CODE_ID, tv.wbs_code, TO_CHAR(tv.pref_st, 'DD-MON-YYYY') AS pref_st, TO_CHAR(tv.pref_fn, 'DD-MON-YYYY') AS pref_fn, tv.ACTL_EFFORT, tv.rollup_effort, tv.overAllStatus, tv.FIELD5, tv.FIELD4, tv.activity_code_id FROM task_view tv, autoplanallocation al WHERE al.project_id = tv.ownerid(+) and al.task_id = tv.taskid(+) and tv.ownertype = 'Prj' AND tv.ownerid = 267157 AND (tv.overAllStatus = 'All' OR 'All' = 'All') AND (TaskId IN ((SELECT xyz FROM (SELECT ToItemID xyz FROM ItemTraceability it WHERE it.FromOwnerType = 'Prj' AND it.FromOwnerID = 267157 AND it.FromItemType = it.FromItemType AND it.FromChildItemType = 'USTRY' AND it.FromItemID = 15334208 AND it.ToOwnerType = 'Prj' AND it.ToOwnerID = 267157 AND it.ToItemType = it.ToItemType AND it.ToChildItemType = 'Tsk' UNION ALL SELECT FromItemID FROM ItemTraceability it WHERE it.ToOwnerType = 'Prj' AND it.ToOwnerID = 267157 AND it.ToItemType = it.ToItemType AND it.ToChildItemType = 'USTRY' AND it.ToItemID = 15334208 AND it.FromOwnerType = 'Prj' AND it.FromOwnerID = 267157 AND it.FromItemType = it.FromItemType AND it.FromChildItemType = 'Tsk')))) ORDER BY UPPER(wbs_code) ASC;
I do not think there is a native way of parsing nested cursors using SQL or PL/SQL code. In Java with an Oracle JDBC database driver, you can: Use oracle.jdbc.driver.OraclePreparedStatement.executeQuery to get a java.sql.ResultSet Which can be cast to an oracle.jdbc.driver.OracleResultSet Then you can iterate through the rows of the result set and for each row you can use oracle.jdbc.driver.OracleResultSet.getCursor() to get the nested cursor. You can then iterate through that nested cursor in exactly the same way you iterated through the outer cursor to extract rows from the nested cursor. You should then close the nested cursor (although it will be automatically closed when the containing parent cursor is closed). Finally, close the parent cursor. If you want an SQL solution then do not return a cursor and return a nested table collection data type instead. Or, for a single row with multiple columns, return an object type: CREATE TYPE date_range_obj AS OBJECT( start_date DATE, end_date DATE ) / CREATE FUNCTION HCLT_GET_TASK_DATES( i_ownerid IN autoplanallocation.project_id%TYPE, i_itemid IN autoplanallocation.task_id%TYPE ) RETURN date_range_obj IS v_range date_range_obj; begin SELECT date_range_obj(MIN(pref_start), MAX(pref_finish)) INTO v_range FROM autoplanallocation WHERE project_id = i_ownerid AND task_id = i_itemid; RETURN v_range; END; / Then, for example: SELECT HCLT_GET_TASK_DATES(1,2).start_date, HCLT_GET_TASK_DATES(1,2).end_date FROM DUAL; db<>fiddle here
If you are able to change this design, then it would be better to do in plain join and aggregation (or possibly with left join lateral in case of low cardinality input). But there's a way to achieve the desired result with plain SQL in 11g and above using the ability of dbms_xmlgen package to process arbitrary cursor. Below is the code: create table t_lkp (id,dt) as select trunc(level/4 + 1) , date '2022-01-01' + level from dual connect by level < 11 create or replace function f_lkp ( p_id in int ) return sys_refcursor as o_res sys_refcursor; begin open o_res for select min(dt) as dtfrom , max(dt) as dtto from t_lkp where id = p_id; return o_res; end; / with a as ( select level as i, dbms_xmlgen.getxmltype( /*ctx doesn't accept sys_refcursor, so we had to create a context*/ ctx => DBMS_XMLGEN.NEWCONTEXT(f_lkp(level)) ) as val from dual connect by level < 6 ) select i , xmlquery( '/ROWSET/ROW/DTFROM/text()' passing a.val returning content null on empty ) as dtfrom , xmlquery( '/ROWSET/ROW/DTTO/text()' passing a.val returning content null on empty ) as dtto from a I | DTFROM | DTTO -: | :------------------ | :------------------ 1 | 2022-01-02 00:00:00 | 2022-01-04 00:00:00 2 | 2022-01-05 00:00:00 | 2022-01-08 00:00:00 3 | 2022-01-09 00:00:00 | 2022-01-11 00:00:00 4 | null | null 5 | null | null db<>fiddle here Please note, that it will open too many cursors in case of large input dataset and parallel processing, which will dramatically consume resourses. So it would be much better to use plain join.
How to modify column data-type while column is in used
I have problem while I use SELECT query. Unfortunettly, the ID is store as VARCHAR which is big mistake and right now I have problem in following function FUNCTION GET_SUB_PROJECTS(p_currentUserId IN VARCHAR,p_projectId IN INT) RETURN SYS_REFCURSOR IS rc SYS_REFCURSOR; -- getSubProject BEGIN OPEN rc FOR SELECT p.*, a.number_ AS activityNumber, a.description AS activityDescription FROM projects p LEFT JOIN project_users_schedule_dates pusd ON pusd.ProjectID = p.ProjectID AND pusd.UserID = p_currentUserId LEFT JOIN activities a ON a.id = p.activity LEFT JOIN responsible_persons rp ON rp.ProjectID = p.ProjectID AND rp.UserID = p_currentUserId LEFT JOIN users u ON u.UserID = p_currentUserId WHERE (u.User_roleID = 1 AND p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId) OR (( (p.Responsible_person_id = p_currentUserId OR p.Delivery_contact = p_currentUserId OR rp.UserID = p_currentUserId OR (pusd.UserID = p_currentUserId AND SYSTIMESTAMP BETWEEN TO_DATE(pusd.StartDate,'YYYY-MM-DD') AND TO_DATE(pusd.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY AND SYSTIMESTAMP BETWEEN TO_DATE(p.StartDate,'YYYY-MM-DD') AND TO_DATE(p.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY)) ) AND p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId) ORDER BY p.CustomName; RETURN rc; END GET_SUB_PROJECTS; When I call function it needs to return data, but it doesn't. Somehow, here p.Responsible_person_id and p.Delivery_contact needs to be NUMBER but somehow it is VARCHAR When I call function I use SELECT PROJECT_PACKAGE.GET_SUB_PROJECTS('199',141) FROM DUAL I found one solution to modify but It throw me error like Error report - ORA-01439: column to be modified must be empty to change datatype 01439. 00000 - "column to be modified must be empty to change datatype" What to do in this situation ? What is the best method to solve this issue ?
You can change the data type of a column online using dbms_redefinition create table t ( c1 varchar2(10) primary key ); create table t_new ( c1 number(10, 0) primary key ); insert into t values ( '1.0000' ); commit; begin dbms_redefinition.start_redef_table ( user, 't', 't_new', col_mapping => 'to_number ( c1 ) c1', options_flag => dbms_redefinition.cons_use_rowid ); end; / exec dbms_redefinition.sync_interim_table ( user, 't', 't_new' ); exec dbms_redefinition.finish_redef_table ( user, 't', 't_new' ); desc t Name Null? Type C1 NOT NULL NUMBER(10) select * from t; C1 1 There are also options to copy constraints, triggers, indexes, etc. automatically in this process.
Oracle Trigger with UPDATE OF ( column name identical with table)
i have a problem with my column who has the same name as one of my tables. I can not use table.column in this situation repres was a table in the windev database and a column in commerc database and devent table where i create this trigger When i do : AFTER UPDATE OF etat,total, devent.repres I Have : ERROR line 2, col 35, ending_line 2, ending_col 35, Found '.', Expecting: , or ON OR This is my code: CREATE OR REPLACE TRIGGER WINDEV_AES_UPDATE AFTER UPDATE OF etat,total, repres ON COMMERC.DEVENT FOR EACH ROW DECLARE BEGIN IF UPDATING AND :OLD.etat != :NEW.etat THEN INSERT INTO windev.aes (code) SELECT (:NEW.CODE) FROM DUAL WHERE NOT EXISTS (SELECT * FROM windev.aes WHERE code = :NEW.CODE); UPDATE windev.aes SET aes.update_flag = 1 WHERE aes.code = :NEW.CODE; END IF; IF UPDATING AND :OLD.total != :NEW.total THEN INSERT INTO windev.aes (code) SELECT (:NEW.CODE) FROM DUAL WHERE NOT EXISTS (SELECT * FROM windev.aes WHERE code = :NEW.CODE); UPDATE windev.aes SET aes.update_flag = 1 WHERE aes.code = :NEW.CODE; END IF; END; / I hope you tell me how resolve this epic problem ;-)
Oracle Merge statement error in procedure package body
I'm struggling trying to make this procedure to work, I have the following code inside my package body: PACKAGE BODY PKG_DM_TRANS_DIMENSIONES AS PROCEDURE SP_DM_TRANS_DIM_CUENTA AS vNumRegistrosDimCuentas NUMBER; BEGIN SELECT COUNT(*) INTO vNumRegistrosDimCuentas FROM DIM_CUENTAS; IF (vNumRegistrosDimCuentas <> 0) THEN MERGE INTO DIM_CUENTAS DIMC USING ( SELECT * FROM ( SELECT DIM.FNT_CUENTA_ID AS DIM_CUENTA_ID, C.CUE_ID AS FNT_CUENTA_ID, R.REG_REGION AS REGION, P.PAI_PAIS AS PAIS, E.EDI_NOMBRE_EDIFICIO AS EDIFICIO, C.CUE_CUENTA, TIC.TIC_TIPO_CONTACTO, C.CUE_STATUS, CASE WHEN DIM.FNT_CUENTA_ID IS NULL THEN 1 WHEN R.REG_REGION <> DIM.REGION OR P.PAI_PAIS <> DIM.PAIS OR E.EDI_NOMBRE_EDIFICIO <> DIM.EDIFICIO OR C.CUE_CUENTA <> DIM.CUENTA OR TIC.TIC_TIPO_CONTACTO <> DIM.TIPO_CONTACTO THEN 2 ELSE 0 END AS TIPO_FILA FROM STA_EDIFICIOS_EXTRACCION E LEFT JOIN STA_PAISES_EXTRACCION P ON E.EDI_PAI_ID = P.PAI_ID LEFT JOIN STA_REGIONES_EXTRACCION R ON P.PAI_REG_ID = R.REG_ID LEFT JOIN EUB_EDIFICIO_UBICACION EUB ON EUB.EUB_EDI_ID = E.EDI_ID LEFT JOIN STA_CUENTAS_EXTRACCION C ON C.CUE_EUB_ID = EUB.EUB_ID LEFT JOIN STA_TIPOS_CONTACTO_EXTRACCION TIC ON TIC.TIC_ID = C.CUE_TIC_ID LEFT JOIN DIM_CUENTAS DIM ON (C.CUE_ID = DIM.FNT_CUENTA_ID AND DIM.CUENTA_STATUS = 1) ) ) Q ON (DIMC.FNT_CUENTA_ID = Q.TIPO_FILA) WHEN MATCHED THEN INSERT (DIMC.REGION, DIMC.PAIS, DIMC.EDIFICIO, DIMC.CUENTA, DIMC.TIPO_CONTACTO, DIMC.CUENTA_FECHA_CREACION, DIMC.FNT_CUENTA_ID) VALUES (Q.REGION, Q.PAIS, Q.EDIFICIO, Q.CUE_CUENTA, Q.TIC_TIPO_CONTACTO, TO_TIMESTAMP(sysdate, 'MM/DD/YYYY HH24:MI:SS'), Q.FNT_CUENTA_ID) WHEN NOT MATCHED THEN UPDATE SET DIMC.CUENTA_STATUS = 0 WHERE DIMC.CUENTA_STATUS = 1 -- <- dummy update stmt ELSE ..... -- else statement code working fine... END IF; END SP_DM_TRANS_DIM_CUENTA; END PKG_DM_TRANS_DIMENSIONES; I'm getting erros at the line MERGE INTO DIM_CUENTAS DIMC Saying "Statement ignored" and then, another error at: INSERT (DIMC.REGION, DIMC.PAIS, DIMC.EDIFICIO, DIMC.CUENTA, DIMC.TIPO_CONTACTO, DIMC.CUENTA_FECHA_CREACION, DIMC.FNT_CUENTA_ID) VALUES (Q.REGION, Q.PAIS, Q.EDIFICIO, Q.CUE_CUENTA, Q.TIC_TIPO_CONTACTO, TO_TIMESTAMP(sysdate, 'MM/DD/YYYY HH24:MI:SS'), Q.FNT_CUENTA_ID) saying "missing keyword". Is it possible to use the merge statement in a SP? I'm new to Oracle so I really don't know if what I'm trying to do is possible or if there's something wrong with my code. Thanks for any help, I would really appreaciate it.
I think that you swapped commands - after when matched you should put update statement and after not matched - insert. Similar example worked for me, but after swapping statements I got ORA-00905 missing keyword. So correct version is: merge into t1 using (select * from t2) t2 on (t1.id = t2.id) when matched then update set t1.name = t2.name when not matched then insert (id, name) values (t2.id, t2.name)
How to use not exists with insert?
I'm trying to frame the below query but it always gives me the error "SQL command not properly ended". How do i use it?? INSERT INTO PROGRAM_KPI (AMSPROGRAMID,MASTER_KPI_ID,LASTUPDATEDBYDATALOAD) (SELECT 'PRG-026',MASTER_KPI_ID,to_char(sysdate,'dd-mon-yy hh.mi.ss') from kpi_master) WHERE NOT EXISTS(select * from insight_master where amsprogramid = V_PROGRAMID and inamsscope = 1 and tickettype = 'INCIDENT' and TICKETSUBMITDATE is not null);
Please try this..(Removing the brackets and formating the code) INSERT INTO program_kpi (amsprogramid, master_kpi_id, lastupdatedbydataload) SELECT 'PRG-026', master_kpi_id, TO_CHAR (SYSDATE, 'dd-mon-yy hh.mi.ss') FROM kpi_master WHERE NOT EXISTS ( SELECT * FROM insight_master WHERE amsprogramid = v_programid AND inamsscope = 1 AND tickettype = 'INCIDENT' AND ticketsubmitdate IS NOT NULL); But What is the relation between table program_kpi and insight_master ? There seems to be no join between the inner and outer subquery.