How to debug this plsql code? - oracle

I am getting error while executing ps-sql procedure.
below is my script.
set serveroutput on size 100000
set echo off
set feedback off
set lines 300
declare
cursor sessinfo is
SELECT NVL(s.username, '(oracle)') AS username,
s.osuser,
s.sid,
s.serial#,
p.spid,
s.status,
s.module,
s.machine,
s.program,
TO_CHAR(s.logon_Time,'DD-MON-YYYY HH24:MI:SS') AS logon_time,
s.last_call_et/3600 last_call_et_Hrs,
lpad(t.sql_text,30) "Last SQL"
from gv$session s,
gv$sqlarea t,
gv$process p
where s.sql_address = t.address and
s.sql_hash_value =t.hash_value and
p.addr=s.paddr and
s.status='INACTIVE' and
s.last_call_et > (3600)
order by last_call_et;
sess sessinfo%rowtype;
sql_string1 Varchar2(2000);
sql_string2 Varchar2(2000);
begin
open sessinfo;
loop
fetch sessinfo into sess;
exit when sessinfo%notfound;
sql_string1 := 'sid=' || sess.sid ||
' serail#=' || sess.serial# ||
' machine=' || sess.machine ||
' program=' || sess.program ||
' username=' || sess.username ||
' Inactive_sec=' || sess.last_call_et ||
' OS_USER=' || sess.osuser;
sql_string2 := 'alter system kill session ' || chr(39) ||
sess.sid || ',' || chr(39) || sess.serial# || ';';
dbms_output.put_line(sql_string1);
dbms_output.put_line(sql_string2);
end loop;
close sessinfo;
end;
/
quit;
i am getting below error. please help me.
[oracle#localhost ~]$ sqlplus -s '/as sysdba' #inactive12.sql
sql_string1:='sid='||sess.sid||' serail#='||sess.serial#||' machine='||sess.machine||' program='||sess.program||' username='||sess.username||' Inactive_sec='||sess.last_call_et||' OS_USER='||sess.osuser;
*
ERROR at line 12:
ORA-06550: line 12, column 165:
PLS-00302: component 'LAST_CALL_ET' must be declared
ORA-06550: line 12, column 1:
PL/SQL: Statement ignored

You aliased last_call_et as last_call_et_hrs, so the cursor doesn't see last_call_et anymore, use the aliased column last_call_et_hrs.

Related

Why does manually running SQL block work but using EXECUTE IMMEDIATE on the same string doesn't?

The following procedure is failing with a "ORA-0097: missing equal sign error".
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_USER_ID_' || ENVIRONMENT || ' = ' || '''' || BATCH_USER_ID || '''' || ',' ||
'BATCH_START_DATE_' || ENVIRONMENT || ' = TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ') ' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'NULL' || '
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
END IF;
COMMIT;
END;
GO
While debugging the issue, we replaced the EXECUTE IMMEDIATE statements with DBMS_OUTPUT.PUT_LINE statements. After doing so, the procedure returned a string (below) that executed successfully with no syntax errors.
UPDATE AMEPSA.ETL_BATCH_MASTER
SET BATCH_STATUS_STAGE = 'Running',
BATCH_JOB_NAME_STAGE = 'wf_TADM_Stage',
BATCH_END_DATE_STAGE = TO_DATE('08/14/2017 15:42:00', 'MM/DD/YYYY HH24:MI:SS')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
Why would the EXECUTE IMMEDIATE statement think it's missing an equals sign when the resulting string returned from the DBMS_OUTPUT.PUT_LINE statement is syntactically correct?
Full exception from Informatica:
Severity: ERROR Timestamp: 8/15/2017 9:46:10 AM Node: didre2007
Thread: TRANSF_1_1_1 Process ID: 9072 Message Code: CMN_1022 Message:
Database driver error... CMN_1022 [ ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14 ORA-06512:
at line 2
Database driver error... Function Name : ExecuteSP
Oracle Fatal Error Database driver error... Function Name : ExecuteSP
Oracle Fatal Error]
It looks like the parameter values being passed into the procedure have single quotes; specifically the first one, but possibly all of them. You can replicate by calling it directly:
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', '''Running''', '''someuser''', '''wf_TADM_Stage''');
which gets
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
or just
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', 'Running', 'someuser', 'wf_TADM_Stage');
which goes into the other branch and gets:
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 6
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
With debugs showing the code before it's executed you can see it ends up trying to run this:
UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_'STAGE' = 'Running',
BATCH_JOB_NAME_'STAGE' = 'wf_TADM_Stage',BATCH_USER_ID_'STAGE' = 'someuser',BATCH_START_DATE_'STAGE' = TO_DATE('08/15/2017 19:37:00', 'MM/DD/YYYY HH24:MI:SS') ,BATCH_END_DATE_'STAGE' = NULL
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
with inappropriate quotes; the BATCH_STATUS_'STAGE' construct is throwing the exception.
If called without those extra single quotes, what you've shown works, in either branch.
So you need to look into why Informatica is adding those single quotes - possibly just a developer's confusion about how to handle strings as arguments - and stop it doing that. The problem isn't in the code you showed, and without seeing the Informatica code, I can't be more specific about how it should be fixed.
Incidentally, in comments it was mentioned that you could use bind variables via the using clause, and not convert sysdate to a string and back; it's nothing to do with the error you're getting, but that might look like:
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_USER_ID_' || ENVIRONMENT || ' = :BATCH_USER_ID,'
|| ' BATCH_START_DATE_' || ENVIRONMENT || ' = SYSDATE,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = NULL'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME, BATCH_USER_ID;
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = SYSDATE'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME;
END IF;
END;

Procedure failed due to ORA-00920: invalid relational operator

Getting below error while executing in 12c oracle,but it is working fine when it was in oracle 10.2.0.4 :
Procedure proc_up_dts_product_cat_dynsql failed due to ORA-00920: invalid
relational operator
Here is the procedure :
CREATE OR REPLACE PROCEDURE SEAPROB.proc_up_dts_product_cat_dynsql(tablename IN varchar)
AS
dynamicsql varchar(8000);
ID int;
DTS_Segment_op varchar2(10);
DTS_Segment varchar2(15);
DTS_Segment_where varchar2(255);
DateEntered_op varchar2(10);
DateEntered varchar2(30);
DateEntered_where varchar2(255);
Svc_Name_op varchar2(10);
Svc_Name varchar2(100);
Svc_Name_where varchar2(255);
Product_Category varchar2(75);
Priority int;
combined_status_where varchar2(255);
refdate date ;
CURSOR PrivCursor
IS
SELECT
ID,
DTS_Segment_op,
Nvl(upper(trim(DTS_Segment)),' '),
DateEntered_op,
CASE WHEN dateentered='%' THEN dateentered
WHEN dateentered LIKE '%/%/____' THEN To_Char(To_Date(dateentered,'MM/DD/YYYY'),'YYYY-MM-DD')
WHEN dateentered LIKE '%/%/__' THEN To_Char(To_Date(dateentered,'MM/DD/YY'),'YYYY-MM-DD')
WHEN dateentered LIKE '''%/%/%'' % ''%/%/%''' THEN ''''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,1)+1,InStr(dateentered,'''',1,2)-InStr(dateentered,'''',1,1)-1),'MM/DD/YY'),'YYYY-MM-DD')||''' and '''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,3)+1,InStr(dateentered,'''',1,4)-InStr(dateentered,'''',1,3)-1),'MM/DD/YY'),'YYYY-MM-DD')||''''
ELSE dateentered END AS dateentered,
Svc_Name_op,
Nvl(upper(trim(Svc_Name)),' '),
Product_Category,
Priority
FROM tbl_dts_pt_lookup order by priority desc;
BEGIN
refdate := ADD_MONTHS(to_date(SYSDATE,'dd-mon-yy'),-6) ;
OPEN PrivCursor;
-- Loop through all the rows in the tbl_dts_category_lookup table
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
WHILE PrivCursor%found
LOOP
-- Create dynamic SQL
--define case statements for where clause components
combined_status_where := ' where (DTS_Cm_DisputeStatus <>'|| '''C''' || ' OR ( DTS_Cm_DisputeStatus='|| '''C''' || ' AND DTS_CM_CLOSEDATE >= '''||refdate||'''))' ;
dts_segment_where := case when dts_segment='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(segment),chr(0),''' || ''')),''' || ' '') ' || dts_segment_op || ' ''' || dts_segment || '''' end;
svc_name_where := case when svc_name='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(dts_cm_servicename),chr(0),''' || ''')),''' || ' '') ' || svc_name_op || ' ''' || svc_name || '''' end ;
dateentered_where := case when dateentered='%' then ' and 1=1'
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
else ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') ' || dateentered_op || ' ''' || dateentered || '''' end ;
dynamicsql := 'update '||tablename||' set product_cat_id=' || cast(id as varchar) ||', product_category =''' || product_category || '''';
--add where clause
dynamicsql := dynamicsql || combined_status_where || dts_segment_where || dateentered_where || svc_name_where;
EXECUTE IMMEDIATE dynamicsql;
COMMIT;
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
END LOOP;
CLOSE PrivCursor;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Procedure proc_up_dts_product_cat_dynsql failed due to '||SQLERRM);
END proc_up_dts_product_cat_dynsql;
/
The database hurls ORA-00920: invalid relational operator when we submit a SQL statement with a syntax error in a WHERE clause. Usually it's a typo. This is extremely easy to do in dynamic SQL, because we cannot see the whole statement except at run time.
You haven't posted the generated update statement. Well you can't, as your exception handling doesn't display it. Pro tip: when working with dynamic SQL always log or display the generated statement, in the exception block if nowhere else:
dbms_output.put_line('generated statement:'|| dynamicsql);
So this is just a guess but this line looks suspicious ...
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
... because it appears to generate a BETWEEN statement with no AND clause. The BETWEEN operator requires two bounds.
But it could be many things. You may be running with an unusual combination of parameters which generates an invalid statement. You need better logging.

I'm getting this error when ever I'm executing my stored procedure " PLS-00103"

I'm trying to execute stored procedure, I'm getting stuck in 54 line 'EXECUTE IMMEDIATE' basically. I'm passing SQL statement into for loop.Please let me know I'm doing wrong somewhere?
CREATE OR REPLACE Procedure DE_DUP_PROC (Dy_File_Name in USER_TABLES.table_name%type,
SUPPLIER_CD in varchar2,
EXT_PHARMA_ID in varchar2,
FLAG_VALUE in varchar2,
DE_REC_COUNT out NUMBER) --RETURN NUMBER
AS
SEQ_NO_SHO Number(38); --EEEE
WYYYYNNN VARCHAR2(250) := 'W2015021';
YYYYNNN VARCHAR2(10);
CUR_DATE Date;
--De_Rec_Count Number(38) := 3456;
DE_DUB_OUTPUT_FILE VARCHAR2(100);
/*CURSOR De_DUB_CUR IS */
DE_DUB_SQL_STATMNT VARCHAR2(3000) := 'SELECT S.TRANS_GUID AS OLD_TRANS_GUID,
H.TRANS_GUID AS NEW_TRANS_GUID,
CASE
WHEN H.TRANS_GUID IS NULL
THEN 0
ELSE 1
END as TRN_STAT,P.INTR_PHARMACY_ID as INT_PHARMACY_ID ,S.EXTRNL_PHARMACY_ID as EXT_PHARMACY_ID ,S.PHARMACY_NM as PHARMACY_NAME ,S.PHARMACY_ADDR as PHARMACY_ADDRESS,
S.SUPPLIERS_PSCR_DRUG_CD as SP_PSCR_DRUG_CD, S.PSCR_DRUG_IPU_CD as PS_DRUG_IPU_CD,''IPU'' as IPU_Value, S.PSCR_DRUG_DESC as PS_DRUG_DESC,
S.DSPNSD_DRUG_PACK_SIZE as DS_DRUG_PACK_SIZE, S.RX_ID as R_ID, S.RX_ITEM_SEQ as R_ITEM_SEQ, S.RX_REPEAT_STATUS as R_REPEAT_STATUS, S.RX_TYP as R_TYPE,
S.EXMT_STATUS as EX_STATUS,S.PSCR_QTY as PS_QTY, S.NRSG_HM_IND as NR_HM_IND,S.RX_DSPNSD_DT as R_DSPNSD_DT, S.RX_DSPNSD_TM as R_DSPNSD_TM,
S.SUPPLIERS_DSPNSD_DRUG_CD as SP_DSPNSD_DRUG_CD, S.DSPNSD_DRUG_IPU_CD as DS_DRUG_IPU_CD, ''IPU'' as IPU_Value2,S.DSPNSD_DRUG_DESC as DS_DRUG_DESC,
S.GENERIC_USE_MARKER as GC_USE_MARKER, S.DSPNSD_UNIT_OF_QTY as DS_UNIT_OF_QTY, S.DSPNSD_QTY as DS_QTY, ''EUR'' as EUR_Value1,S.COST_OF_DSPNSD_QTY as CT_OF_DSPNSD_QTY ,
S.VERBOSE_DOSAGE as VER_DOSAGE FROM
(SELECT stg.*, row_number() over (partition BY key_clmns_hash ORDER BY 1) AS RN FROM '|| Dy_File_Name ||' stg ) s
LEFT JOIN ps_pharmacy p
ON s.extrnl_pharmacy_id = p.extrnl_pharmacy_id
LEFT JOIN ps_rx_hist H
ON h.key_clmns_hash = s.key_clmnS_hash
AND h.rx_dspnsd_dt = s.rx_dspnsd_dt
AND s.supplier_pharmacy_cd = h.SUPPLIER_PHARMACY_CD
AND s.detl_clmns_hash <> h.detl_clmns_hash
WHERE s.RN = 1';
BEGIN
EXECUTE IMMEDIATE 'SELECT count(*) into DE_REC_COUNT
FROM (SELECT stg.*, row_number() over ( partition BY key_clmns_hash ORDER BY 1 ) AS RN FROM '|| Dy_File_Name ||' stg ) s
LEFT JOIN ps_pharmacy p ON s.extrnl_pharmacy_id = p.extrnl_pharmacy_id LEFT JOIN ps_rx_hist H ON h.key_clmns_hash = s.key_clmnS_hash
AND h.rx_dspnsd_dt = s.rx_dspnsd_dt AND s.supplier_pharmacy_cd = h.SUPPLIER_PHARMACY_CD AND s.detl_clmns_hash <> h.detl_clmns_hash WHERE S.RN = 1';
IF DE_REC_COUNT > 0 THEN
--select sysdate into CUR_DATE from dual;
--select PROC_PD_CD into WYYYYNNN from PS_ADMIN.PS_PROC_PD where PD_STRT_DT <= CURRENT_DATE and PD_END_DT >= CURRENT_DATE;
--select PROC_PD_CD into WYYYYNNN from PS_ADMIN.PS_PROC_PD where PD_STRT_DT <= CURRENT_DATE and PD_END_DT >= CURRENT_DATE; -- PD_STRT_DT<='16-AUG-15' and PD_STRT_DT >= '16-AUG-15';
select replace(WYYYYNNN,'W','') into YYYYNNN from dual;
SELECT PS_GET_PROC_PD(SUPPLIER_CD,EXT_PHARMA_ID,YYYYNNN) into SEQ_NO_SHO FROM DUAL;
select 'LRXIE'||FLAG_VALUE||'10_'||SUPPLIER_CD||'_'||EXT_PHARMA_ID||'_'||WYYYYNNN||'_'||SEQ_NO_SHO||'_'||DE_REC_COUNT||'.TXT' into DE_DUB_OUTPUT_FILE from dual;
--DBMS_OUTPUT.PUT_LINE( De_Dub_Output_File );
FOR De_Dub_rec IN EXECUTE IMMEDIATE DE_DUB_SQL_STATMNT
LOOP
dbms_output.enable(100000);
DBMS_OUTPUT.PUT_LINE ('"' || De_Dub_rec.OLD_TRANS_GUID || '"|"' || De_Dub_rec.NEW_TRANS_GUID || '"|' || De_Dub_rec.TRN_STAT || '|' || De_Dub_rec.INT_PHARMACY_ID || '|' || De_Dub_rec.EXT_PHARMACY_ID || '|"' ||
De_Dub_rec.PHARMACY_NAME|| '"|"' || De_Dub_rec.PHARMACY_ADDRESS || '"|' || De_Dub_rec.SP_PSCR_DRUG_CD || '|' || De_Dub_rec.PS_DRUG_IPU_CD || '|"' || De_Dub_rec.IPU_Value || '"|"' ||
De_Dub_rec.PS_DRUG_DESC || '"|' || De_Dub_rec.DS_DRUG_PACK_SIZE || '|"' || De_Dub_rec.R_ID || '"|' || De_Dub_rec.R_ITEM_SEQ || '|' || De_Dub_rec.R_REPEAT_STATUS || '|"' ||
De_Dub_rec.R_TYPE || '"|"' || De_Dub_rec.EX_STATUS || '"|' || De_Dub_rec.PS_QTY || '|' || De_Dub_rec.NR_HM_IND || '|"' || De_Dub_rec.R_DSPNSD_DT || '"|' || De_Dub_rec.R_DSPNSD_TM || '|' ||
De_Dub_rec.SP_DSPNSD_DRUG_CD || '|' || De_Dub_rec.DS_DRUG_IPU_CD|| '|"' || De_Dub_rec.IPU_Value2 || '"|"' || De_Dub_rec.DS_DRUG_DESC|| '"|' || De_Dub_rec.GC_USE_MARKER|| '|"' ||
De_Dub_rec.DS_UNIT_OF_QTY|| '"|' || De_Dub_rec.DS_QTY|| '|"' || De_Dub_rec.EUR_Value1|| '"|' || De_Dub_rec.CT_OF_DSPNSD_QTY || '|"' || De_Dub_rec.VER_DOSAGE || '"');
END LOOP;
DE_REC_COUNT :=0;
ELSE
DE_REC_COUNT :=1;
END IF;
END DE_DUP_PROC;
/
I'm getting this error:
LINE/COL ERROR
-------- -----------------------------------------------------------------
58/44 PLS-00103: Encountered the symbol "IMMEDIATE" when expecting one
of the following:
. ( * # % & - + / at loop mod remainder rem ..
<an exponent (**)> || multiset
The symbol ". was inserted before "IMMEDIATE" to continue.
There are two errors in your code. The first one is the compiler error you get. You can't use an execute immediate in a for loop (which is clearly documented in the manual)
You need to open a cursor and then loop over the cursor. So instead of
FOR De_Dub_rec IN EXECUTE IMMEDIATE DE_DUB_SQL_STATMNT
you need to use something like this:
OPEN De_Dub_cursor FOR DE_DUB_SQL_STATMNT;
LOOP
FETCH De_Dub_cursor INTO de_dub_cursor_record;
EXIT WHEN cv%NOTFOUND;
... do your stuff here
END LOOP;
Of course you will need to declare the cursor De_Dub_cursor and the record variable de_dub_cursor_record. Note that the record variables needs to be defined with all columns that your result returns (which essentially requires a new TYPE to be defined if I'm not mistaken)
The second error you have won't show up until you run the code. You have an INTO variable clause inside your SQL string for the first EXECUTE IMMEDIATE. This will not work. The into clause can not be used like that. You need to remove the into DE_REC_COUNT part from the string literal and use the INTO clause as an option to the execute immediate statement. Something like this:
EXECUTE IMMEDIATE 'SELECT count(*) FROM ....'
INTO DE_REC_COUNT;
Unrelated to your problems, but the select ... from dual can be replaced with a simple assignment.
So instead of
select replace(WYYYYNNN,'W','') into YYYYNNN from dual;
use
YYYYNNN := replace(WYYYYNNN,'W','');
or instead of:
SELECT PS_GET_PROC_PD(SUPPLIER_CD,EXT_PHARMA_ID,YYYYNNN) into SEQ_NO_SHO FROM DUAL;
select 'LRXIE'||FLAG_VALUE||'10_'||SUPPLIER_CD||'_'||EXT_PHARMA_ID||'_'||WYYYYNNN||'_'||SEQ_NO_SHO||'_'||DE_REC_COUNT||'.TXT' into DE_DUB_OUTPUT_FILE from dual;
use
SEQ_NO_SHO := PS_GET_PROC_PD(SUPPLIER_CD,EXT_PHARMA_ID,YYYYNNN);
DE_DUB_OUTPUT_FILE := 'LRXIE'||FLAG_VALUE||'10_'||SUPPLIER_CD||'_'||EXT_PHARMA_ID||'_'||WYYYYNNN||'_'||SEQ_NO_SHO||'_'||DE_REC_COUNT||'.TXT';
First, should be execute immediate 'select count(*) from ...' into DE_REC_COUNT;
That's what I see at first scan, but the fail is at second execute immediate.
There you should create a collection and execute immediate the query and bulk collect into that collection.
Then, you should loop in that collection and do the work that you do(the dbms_output stuff).

table or view does not exist : ORA-00942

I'm trying to create Procedure where I'm passing dynamic table but I'm not able to achieve my goal and getting "PL/SQL: ORA-00942: table or view does not exist".Please let me know if doing wrong somewhere
CREATE OR REPLACE Procedure DE_DUP_PRO1 (Dy_Table_Name in varchar2)
--RETURN NUMBER
AS
v_hol varchar2(300);
CURSOR De_DUB_CUR IS
SELECT S.TRANS_GUID AS OLD_TRANS_GUID,
H.TRANS_GUID AS NEW_TRANS_GUID,
CASE
WHEN H.TRANS_GUID IS NULL
THEN 0
ELSE 1
END as TRN_STAT,
P.INTR_PHARMACY_ID as INT_PHARMACY_ID ,S.EXTRNL_PHARMACY_ID as EXT_PHARMACY_ID ,S.PHARMACY_NM as PHARMACY_NAME ,S.PHARMACY_ADDR as PHARMACY_ADDRESS,
S.SUPPLIERS_PSCR_DRUG_CD as SP_PSCR_DRUG_CD, S.PSCR_DRUG_IPU_CD as PS_DRUG_IPU_CD,'IPU' as IPU_Value, S.PSCR_DRUG_DESC as PS_DRUG_DESC,
S.DSPNSD_DRUG_PACK_SIZE as DS_DRUG_PACK_SIZE, S.RX_ID as R_ID, S.RX_ITEM_SEQ as R_ITEM_SEQ, S.RX_REPEAT_STATUS as R_REPEAT_STATUS, S.RX_TYP as R_TYPE,
S.EXMT_STATUS as EX_STATUS,S.PSCR_QTY as PS_QTY, S.NRSG_HM_IND as NR_HM_IND,S.RX_DSPNSD_DT as R_DSPNSD_DT, S.RX_DSPNSD_TM as R_DSPNSD_TM,
S.SUPPLIERS_DSPNSD_DRUG_CD as SP_DSPNSD_DRUG_CD, S.DSPNSD_DRUG_IPU_CD as DS_DRUG_IPU_CD, 'IPU' as IPU_Value2,S.DSPNSD_DRUG_DESC as DS_DRUG_DESC,
S.GENERIC_USE_MARKER as GC_USE_MARKER, S.DSPNSD_UNIT_OF_QTY as DS_UNIT_OF_QTY, S.DSPNSD_QTY as DS_QTY, 'EUR' as EUR_Value1,S.COST_OF_DSPNSD_QTY as CT_OF_DSPNSD_QTY ,
S.VERBOSE_DOSAGE as VER_DOSAGE
FROM (SELECT stg.*, row_number() over ( partition BY key_clmns_hash ORDER BY 1 ) AS RN FROM Dy_Table_Name stg ) s
-- From( SELECT stg.TRANS_GUID,stg.EXTRNL_PHARMACY_ID,stg.PHARMACY_NM,stg.PHARMACY_ADDR,stg.SUPPLIERS_PSCR_DRUG_CD,stg.PSCR_DRUG_IPU_CD,stg.PSCR_DRUG_DESC,stg.DSPNSD_DRUG_PACK_SIZE,
-- stg.RX_ID,stg.RX_ITEM_SEQ,stg.RX_REPEAT_STATUS,stg.RX_TYP,stg.EXMT_STATUS,stg.PSCR_QTY,stg.NRSG_HM_IND,stg.RX_DSPNSD_DT,stg.RX_DSPNSD_TM,stg.SUPPLIERS_DSPNSD_DRUG_CD,
-- stg.DSPNSD_DRUG_IPU_CD,stg.DSPNSD_DRUG_DESC,stg.GENERIC_USE_MARKER,stg.DSPNSD_UNIT_OF_QTY,stg.DSPNSD_QTY,stg.COST_OF_DSPNSD_QTY,stg.VERBOSE_DOSAGE, row_number() over ( partition BY key_clmns_hash ORDER BY 1 ) AS RN FROM Dy_File_Name stg ) s
LEFT JOIN ps_pharmacy p ON s.extrnl_pharmacy_id = p.extrnl_pharmacy_id LEFT JOIN ps_rx_hist H ON h.key_clmns_hash = s.key_clmnS_hash
AND h.rx_dspnsd_dt = s.rx_dspnsd_dt AND s.supplier_pharmacy_cd = h.SUPPLIER_PHARMACY_CD AND s.detl_clmns_hash <> h.detl_clmns_hash WHERE S.RN = 1;
BEGIN
FOR De_Dub_rec IN De_DUB_CUR
LOOP
DBMS_OUTPUT.PUT_LINE ( De_Dub_rec.OLD_TRANS_GUID || '|' || De_Dub_rec.NEW_TRANS_GUID || '|' || De_Dub_rec.TRN_STAT || '|' || De_Dub_rec.INT_PHARMACY_ID || '|' ||
De_Dub_rec.EXT_PHARMACY_ID || '|' || De_Dub_rec.PHARMACY_NAME|| '|' || De_Dub_rec.PHARMACY_ADDRESS || '|' || De_Dub_rec.SP_PSCR_DRUG_CD || '|' ||
De_Dub_rec.PS_DRUG_IPU_CD || '|' || De_Dub_rec.IPU_Value || '|' || De_Dub_rec.PS_DRUG_DESC || '|' || De_Dub_rec.DS_DRUG_PACK_SIZE || '|' || De_Dub_rec.R_ID || '|' ||
De_Dub_rec.R_ITEM_SEQ || '|' || De_Dub_rec.R_REPEAT_STATUS || '|' || De_Dub_rec.R_TYPE || '|' || De_Dub_rec.EX_STATUS || '|' || De_Dub_rec.PS_QTY || '|' || De_Dub_rec.NR_HM_IND || '|' || De_Dub_rec.R_DSPNSD_DT
|| '|' || De_Dub_rec.R_DSPNSD_TM || '|' || De_Dub_rec.SP_DSPNSD_DRUG_CD || '|' || De_Dub_rec.DS_DRUG_IPU_CD|| '|' || De_Dub_rec.IPU_Value2 || '|' ||
De_Dub_rec.DS_DRUG_DESC|| '|' || De_Dub_rec.GC_USE_MARKER|| '|' || De_Dub_rec.DS_UNIT_OF_QTY|| '|' || De_Dub_rec.DS_QTY|| '|' || De_Dub_rec.EUR_Value1|| '|' ||
De_Dub_rec.CT_OF_DSPNSD_QTY|| '|' || De_Dub_rec.VER_DOSAGE);
END LOOP;
-- RETURN 0;
END DE_DUP_PRO1;
/
After executing I'm getting below
LINE/COL ERROR
-------- -----------------------------------------------------------------
7/7 PL/SQL: SQL Statement ignored
21/106 PL/SQL: ORA-00942: table or view does not exist
36/6 PL/SQL: Statement ignored
36/29 PLS-00364: loop index variable 'DE_DUB_REC' use is invalid
You have to use dynamic sql.
for example;
CREATE OR REPLACE Procedure DE_DUP_PRO1 (
Dy_Table_Name in varchar2
)
AS
v_sql varchar2(1500);
v_clm1 number; -- if clm1 datatype is number
v_clm1 number; -- if clm2 datatype is number
begin
v_sql := 'select clm1, clm2 from ' || Dy_Table_Name;
open cur for v_sql;
loop
FETCH cur INTO v_clm1, v_clm2;
EXIT WHEN cur%NOTFOUND;
-- process v_clm1, v_clm2
end loop;
end DE_DUP_PRO1;
/

UPDATE statements in oracle pl/sql loop with tablenames as parameters

I have a requirement where I need to run set of UPDATE statements in a for loop.
In the cursor there is a column called PROPERTY_ID which is a number and there are many tables
that have this number appended.
For ex: SELECT * FROM PC_ORG_EXT_111(where 111 is the property_id)
This is the code and it's throwing error.
Can anyone assist me if I'm missing something here.
SET SERVEROUTPUT ON SIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
DECLARE
V_PROP_ID VARCHAR(200);
V_CNT NUMBER(25);
V_SQL_STRING VARCHAR2(500);
CURSOR CUR_CON
IS
SELECT * FROM PRE_CONVERSION_UNMERGE_LIST;
BEGIN
FOR REC_CON IN CUR_CON
LOOP
V_PROP_ID := 'PROPARCH.PC_ORG_EXT_' || REC_CON.PROPERTY_ID;
dbms_output.put_line('Property Table Name ' || V_PROP_ID);
EXECUTE IMMEDIATE 'select COUNT(1) from ' ||V_PROP_ID;
EXECUTE IMMEDIATE '
UPDATE SIEBEL.S_ACCNT_POSTN
SET OU_EXT_ID = ' || REC_CON.VALID_SURVIVIR_REC ||'
WHERE OU_EXT_ID = ' || REC_CON.INVALID_SURVIVOR_REC||'
AND OU_EXT_ID IN (SELECT ISAC_ROW_ID
FROM ' || V_PROP_ID || '
WHERE INTEGRATION_ID = '||REC_CON.DELPHI_ID||')
AND POSITION_ID NOT IN
(SELECT POSITION_ID
FROM SIEBEL.S_ACCNT_POSTN
WHERE OU_EXT_ID = '||REC_CON.VALID_SURVIVIR_REC||')';
END LOOP;
END;
Error says :
ORA-00933: SQL command not properly ended
ORA-06512: at line 20
Also let me know if there's a better way of doing it.
Thanks,
Please try this! - Single Quotes has to be Used with escape characters!
EXECUTE IMMEDIATE '
UPDATE SIEBEL.S_ACCNT_POSTN
SET OU_EXT_ID = ''' || REC_CON.VALID_SURVIVIR_REC ||'''
WHERE OU_EXT_ID = ''' || REC_CON.INVALID_SURVIVOR_REC||'''
AND OU_EXT_ID IN (SELECT ISAC_ROW_ID
FROM ' || V_PROP_ID || '
WHERE INTEGRATION_ID = '''||REC_CON.DELPHI_ID||''')
AND POSITION_ID NOT IN
(SELECT POSITION_ID
FROM SIEBEL.S_ACCNT_POSTN
WHERE OU_EXT_ID = '''||REC_CON.VALID_SURVIVIR_REC||''')';

Resources