Unexpected error in PL/SQL case statement - oracle

I'm new in PL/SQL
try to make case for grade but it's showing identifier error
SET serveroutput ON;
SET verify OFF
DECLARE
v_grade CHAR(1) := UPPER(&GPA);
appre VARCHAR2(20);
BEGIN
appre := CASE v_grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
ELSE 'No Such Grade'
END;
DBMS_OUTPUT.PUT_LINE( 'Grade is '|| v_grade || ' is equal to ' || appre );
END;
/
This is error i got
Error report -
ORA-06550: line 2, column 28:
PLS-00201: identifier 'E' must be declared
ORA-06550: line 2, column 11:
PL/SQL: Item ignored

Your issue is with this line:
v_grade CHAR(1) := UPPER(&GPA);
At run time you are prompted for a value for GPA. If you type in just the letter E it resolves to:
v_grade CHAR(1) := UPPER(E);
That requires an identifier e.g. variable called E. You need it to resolve to a string:
v_grade CHAR(1) := UPPER('E');
So change it to this:
v_grade CHAR(1) := UPPER('&GPA');

This works with only 1 modification for '&GPA'
SET serveroutput ON;
SET verify OFF
DECLARE
v_grade CHAR(1) := UPPER('&GPA');
appre VARCHAR2(20);
BEGIN
appre := CASE v_grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
ELSE 'No Such Grade'
END;
DBMS_OUTPUT.PUT_LINE( 'Grade is '|| v_grade || ' is equal to ' || appre );
END;
/
This also works with the other CASE syntax:
SET serveroutput ON;
SET verify OFF
DECLARE
v_grade CHAR(1) := UPPER('&GPA');
appre VARCHAR2(20);
BEGIN
CASE
WHEN v_grade = 'A' THEN appre:='Excellent';
WHEN v_grade = 'B' THEN appre:='Very Good';
WHEN v_grade = 'C' THEN appre:='Good';
ELSE appre := 'No Such Grade';
END CASE;
DBMS_OUTPUT.PUT_LINE( 'Grade is '|| v_grade || ' is equal to ' || appre );
END;
/

Related

How can I increment a date by a few months?

This is my code that I have written:
create or replace procedure UPDATING_LOCATION(P_SHIPMENT_NUM IN NUMBER,
P_SHIPMENT_DESTINATION IN VARCHAR2,
P_ERROR OUT VARCHAR2)
is
begin
UPDATE SHIPMENT S
SET S.SHIPMENT_DESTINATION = P_SHIPMENT_DESTINATION
WHERE S.SHIPMENT_NUM = P_SHIPMENT_NUM;
IF SHIPMENT_NUM = '11'
THEN
TO_DATE('06-05-2020') + 1
ELSE
P_MESSAGE := 'The shipment will be on time, which is ' || P_SHIPMENT_DATE;
EXCEPTION
WHEN OTHERS THEN
P_ERROR := 'UPDATE WAS FAILED FOR SHIPMENT' || P_SHIPMENT_NUM || '- SQL ERROR: '||SQLERRM;
end UPDATING_LOCATION;
You are not using P_SHIPMENT_DATE anywhere in your procedure's parameter list. I think that should be your OUT parameter in your procedure. -
create or replace procedure UPDATING_LOCATION(P_SHIPMENT_NUM IN NUMBER,
P_SHIPMENT_DESTINATION IN VARCHAR2,
P_SHIPMENT_DATE OUT DATE,
P_ERROR OUT VARCHAR2)
is
begin
UPDATE SHIPMENT S
SET S.SHIPMENT_DESTINATION = P_SHIPMENT_DESTINATION
WHERE S.SHIPMENT_NUM = P_SHIPMENT_NUM;
IF SHIPMENT_NUM = '11'
THEN
P_SHIPMENT_DATE := TO_DATE('06-05-2020', 'DD-MM-YYYY') + 1; -- You have to pick this date from somewhere.
P_MESSAGE := 'The shipment will be delayed by 1 day.';
ELSE
P_SHIPMENT_DATE := TO_DATE('06-05-2020', 'DD-MM-YYYY'); -- You have to pick this date from somewhere.
P_MESSAGE := 'The shipment will be on time, which is ' || TO_DATE('05-05-2020', 'DD-MM-YYYY');
END IF;
EXCEPTION
WHEN OTHERS THEN
P_ERROR := 'UPDATE WAS FAILED FOR SHIPMENT' || P_SHIPMENT_NUM || '- SQL ERROR: '||SQLERRM;
end UPDATING_LOCATION;

How to ignore tab/column not exist error in oracle?

I have the following code:
declare
var_cdb varchar2(3);
var_eleven varchar2(2);
...
..
begin
SELECT to_number(substr(version,1,2)) into var_eleven FROM V$INSTANCE;
if var_eleven > 11
then
select cdb into var_cdb from v$database;
if var_cdb = 'YES'
then
....
But executing the PL/SQL code in Oracle 11g I get the following error:
ERROR at line 12:
ORA-06550: line 12, column 9:
PL/SQL: ORA-00904: "CDB": invalid identifier
ORA-06550: line 12, column 2:
PL/SQL: SQL Statement ignored
ORA-06550: line 15, column 43:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 15, column 19:
PL/SQL: SQL Statement ignored
ORA-06550: line 17, column 248:
...
How can I ignore if table/column not exist in this version? I need create a script that execute successfully in 11g up and verify if is cdb and has or not pdbs if the database 12c up.
There are 3 standard ways to do this:
You can use conditional compilation and dbms_db_version package:
declare
v_version pls_integer:= dbms_db_version.version;
v_release pls_integer:= dbms_db_version.release;
v_version_full varchar2(12);
var_cdb varchar2(3);
begin
$IF dbms_db_version.ver_le_11 $THEN
var_cdb := 'NO';
select version into v_version_full from v$instance;
$ELSE
select cdb into var_cdb from v$database;
select version_full into v_version_full from v$instance;
$END
dbms_output.put_line(v_version||'.'||v_release);
dbms_output.put_line(v_version_full);
dbms_output.put_line(var_cdb);
end;
/
Example output from 18.3:
18.0
18.3.0.0.0
YES
To use xmltype(cursor({your query with *})) and parse its' output:
select
nvl(version_full, version) as db_version
from xmltable(
'/'
passing xmltype(cursor(select * from v$instance))
columns
version varchar2(12) path '/ROWSET/ROW/VERSION',
version_full varchar2(12) path '/ROWSET/ROW/VERSION_FULL'
);
So if your query doesn't return version_full column to xml, you get null in version_full without errors.
To check if this query really exists in the table/view and use dynamic sql to return only required data:
DECLARE
v_sql varchar2(32000);
select_list varchar2(100);
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
val varchar2(100);
cursor_status INTEGER;
PROCEDURE print_rec(i int, rec in DBMS_SQL.DESC_REC) IS
BEGIN
DBMS_OUTPUT.PUT_LINE(i || '. ' || rec.col_name);
--DBMS_OUTPUT.PUT_LINE('col_type = ' || rec.col_type);
--DBMS_OUTPUT.PUT_LINE('col_maxlen = ' || rec.col_max_len);
--DBMS_OUTPUT.PUT_LINE('col_name = ' || rec.col_name);
--DBMS_OUTPUT.PUT_LINE('col_name_len = ' || rec.col_name_len);
--DBMS_OUTPUT.PUT_LINE('col_schema_name = ' || rec.col_schema_name);
--DBMS_OUTPUT.PUT_LINE('col_schema_name_len = ' || rec.col_schema_name_len);
--DBMS_OUTPUT.PUT_LINE('col_precision = ' || rec.col_precision);
--DBMS_OUTPUT.PUT_LINE('col_scale = ' || rec.col_scale);
--DBMS_OUTPUT.PUT_LINE('col_null_ok = ' || case when rec.col_null_ok 'true' else 'false' end);
END;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
select
listagg(column_name, ',') within group(order by column_id) as select_list
into select_list
from all_tab_columns tc
where tc.owner='SYS'
and table_name='V_$INSTANCE'
and column_name like 'VERSION%';
v_sql := 'select '|| select_list || ' from v$instance';
DBMS_SQL.PARSE(c, v_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
for i in 1..col_cnt loop
dbms_sql.define_column(c,i,val,100);
end loop;
/*
* Following loop could simply be for j in 1..col_cnt loop.
* Here we are simply illustrating some of the PL/SQL table
* features.
*/
col_num := rec_tab.first;
IF (col_num IS NOT NULL) THEN
LOOP
print_rec(col_num, rec_tab(col_num));
col_num := rec_tab.next(col_num);
EXIT WHEN (col_num IS NULL);
END LOOP;
END IF;
LOOP
cursor_status := dbms_sql.fetch_rows(c);
for i in 1..col_cnt loop
dbms_sql.column_value(c,i,val);
DBMS_OUTPUT.PUT_LINE(rec_tab(i).col_name||':'||val);
end loop;
EXIT WHEN cursor_status != 100;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(c);
END;
/
Result:
1. VERSION
2. VERSION_LEGACY
3. VERSION_FULL
VERSION:18.0.0.0.0
VERSION_LEGACY:18.0.0.0.0
VERSION_FULL:18.3.0.0.0

initializing schema object type vs. package type

I have the following code:
declare
type r_rec is record (col1 number, col2 varchar2(10));
type t_rec is table of r_rec;
v_rec t_rec := t_rec();
begin
v_rec.EXTEND(2);
v_rec(1).col1 := 1;
v_rec(1).col2 := 'one';
v_rec(2).col1 := 2;
v_rec(2).col2 := 'two';
for i in v_rec.first .. v_rec.last
loop
dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2);
end loop;
end;
Which works as expected.
Instead of PLSQL type I want to use schema object type and the code becomes:
create or replace type r_rec as object (col1 number, col2 varchar2(10));
/
create or replace type t_rec as table of r_rec;
/
declare
v_rec t_rec := t_rec();
begin
v_rec.EXTEND(2);
v_rec(1).col1 := 1;
v_rec(1).col2 := 'one';
v_rec(2).col1 := 2;
v_rec(2).col2 := 'two';
for i in v_rec.first .. v_rec.last
loop
dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2);
end loop;
end;
/
But, this time, the following error occurs:
ORA-06533: Subscript beyond count ORA-06512: at line 7 ORA-06512: at
"SYS.DBMS_SQL", line 1721
Can someone spot what am I doing wrong, please?
Your first code sample fails with ORA-06533: Subscript beyond count db<>fiddle.
To fix it you need to EXTEND the collection:
declare
type r_rec is record (col1 number, col2 varchar2(10));
type t_rec is table of r_rec;
v_rec t_rec := t_rec();
begin
v_rec.EXTEND(2);
v_rec(1).col1 := 1;
v_rec(1).col2 := 'one';
v_rec(2).col1 := 2;
v_rec(2).col2 := 'two';
for i in v_rec.first .. v_rec.last
loop
dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2);
end loop;
end;
/
Your second code sample has the same issue; you need to EXTEND the collection but you also need to initialise the objects:
create or replace type r_rec as object (col1 number, col2 varchar2(10));
create or replace type t_rec as table of r_rec;
declare
v_rec t_rec := t_rec();
begin
v_rec.EXTEND(2);
v_rec(1) := r_rec( 1, 'one' );
v_rec(2) := r_rec( 2, 'two' );
for i in v_rec.first .. v_rec.last
loop
dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2);
end loop;
end;
/
Which outputs:
col1 = 1, col2 = one
col1 = 2, col2 = two
or you can initialise the values inline in the declaration:
declare
v_rec t_rec := t_rec( r_rec( 1, 'one' ), r_rec( 2, 'two' ));
begin
for i in v_rec.first .. v_rec.last
loop
dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2);
end loop;
end;
/
db<>fiddle

ORA-01007: variable not in select list while fetch c2 into cursor2

I have oracle pl/sql procedure with below:
TYPE Paycomp2 IS RECORD(
Row_Id VARCHAR2(15),
Created DATE,
Created_By VARCHAR2(15),
Last_Upd DATE,
Last_Upd_By VARCHAR2(15),
Modification_Num NUMBER(10),
Conflict_Id VARCHAR2(15),
Comp_Price NUMBER(10),
Access_Level VARCHAR2(30),
Comp_Name VARCHAR2(30),
Depends_On VARCHAR2(30),
Gold_Cat VARCHAR2(30),
Order_Type VARCHAR2(30),
Parent_Id VARCHAR2(15),
Price_Plan VARCHAR2(30),
TYPE VARCHAR2(30),
Check_Flag VARCHAR2(1),
PREPAID_INIT_PRICE number(10),
DB_LAST_UPD date,
DB_LAST_UPD_SRC varchar2(50),
Unit_Type varchar2(30),
M2M_CATEGORY varchar2(30));
TYPE Paycomp IS REF CURSOR;
C2 Paycomp;
Cursor2 Paycomp2;
when I do the below operation
FETCH C2 INTO Cursor2;
I am getting this error :
ORA-01007: variable not in select list error.
This piece of script has worked previously.
How to resolve this issue?
script
Vordertype := 'Migration Prepaid - Postpaid';
Curcomp_Sql := Curcomp_Sql || Vordertype || '''' || ' union all ' || '' || Curcomp2sql || '' ||
Vordertype || '''';
OPEN C2 FOR Curcomp_Sql;
Sadmin.Pkg_Spliter.Prcsplitchar(Ppaycompstr, ';', Arrcomplist);
Vtotalcompprc := 0;
Arrcount := Arrcomplist.Count;
BEGIN
Dbms_output.put_line('reached17');
LOOP
FETCH C2
INTO Cursor2;
Dbms_output.put_line('reached18');
EXIT WHEN C2%NOTFOUND;
-- Processing each entry from Array
Compfndflg := 0;
dbms_output.put_line('arrCount 0: reached');
FOR Counter IN 1 .. Arrcount
LOOP
Vstrcommand := Arrcomplist(Counter);
dbms_output.put_line('arrCount : reached');
Sadmin.Pkg_Spliter.Prcsplitchar(Vstrcommand, '?', Arrdisclist);
IF Arrdisclist.Count <> 0 THEN
dbms_output.put_line('arrCount : reached1');
-- Extracting the ? seperated values and putting them into variables
Vcompname := Arrdisclist(1);
--dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||VCOMPNAME);
BEGIN
-- Added by Accenture
IF Vcompname IS NOT NULL THEN
--dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||ARRDISCLIST(1)||'-'||ARRDISCLIST(2)||'-'||ARRDISCLIST(3));
SELECT COUNT(0)
INTO v_Count_Exist
FROM Siebel.Cx_Paycomp_Mtx a, Siebel.Cx_Paycomp_Mtx b
WHERE a.Row_Id = b.Parent_Id
AND a.Order_Type = Vordertype
AND b.Type = 'Payment Component'
AND b.Comp_Name = Vcompname;
IF (v_Count_Exist = 0) THEN
Err_Msg := 'Invalid Payment Component in String';
Result_Out := '74';
Errflg := 1;
--dbms_output.put_line('Counter 2' || counter);
--dbms_transaction.rollback;
RAISE Error_Out;
END IF;
END IF;
--dbms_output.put_line('Counter 3' || CURSOR2.comp_name);
IF Vcompname = Cursor2.Comp_Name
--and VCOMPNAME != '3'
THEN
Compfndflg := 1;
EXIT;
END IF;
END;
END IF;
END LOOP;
---DBMS_OUTPUT.PUT_LINE('VCOMPNAME, COMPFNDFLG'||VCOMPNAME||','||COMPFNDFLG);
--dbms_output.put_line('CURSOR2.comp_name :'||CURSOR2.comp_name||' - COMPFNDFLG :'||COMPFNDFLG);
IF Compfndflg != 1 THEN
IF Temp_Comp_String IS NULL THEN
Temp_Comp_String := Cursor2.Comp_Name || '?0?;';
---DBMS_OUTPUT.PUT_LINE('STRING 1'||TEMP_COMP_STRING);
ELSE
Temp_Comp_String := Temp_Comp_String || Cursor2.Comp_Name || '?0?;';
---DBMS_OUTPUT.PUT_LINE('STRING 2'||TEMP_COMP_STRING);
END IF;
--- END IF;
ELSE
IF Temp_Comp_String IS NULL THEN
Temp_Comp_String := Arrdisclist(1) || '?' || Arrdisclist(2) || '?' ||
Arrdisclist(3) || ';';
---DBMS_OUTPUT.PUT_LINE('STRING 3'||TEMP_COMP_STRING);
ELSE
Temp_Comp_String := Temp_Comp_String || Arrdisclist(1) || '?' || Arrdisclist(2) || '?' ||
Arrdisclist(3) || ';';
---DBMS_OUTPUT.PUT_LINE('STRING 4'||TEMP_COMP_STRING);
END IF;
-- end if;
--- END IF;
END IF;
END LOOP;
END;
Curcomp_Sql VARCHAR2(2000) := 'SELECT mtx2.*
FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2
WHERE mtx2.parent_id = mtx1.row_id
AND mtx2.comp_name <> ''Security Deposit''
AND mtx2.TYPE = ''Payment Component''
AND mtx1.order_type = ''';
Curcomp2sql VARCHAR2(2000) := 'SELECT mtx2.*
FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2
WHERE mtx2.parent_id = mtx1.row_id
AND mtx2.comp_name = ''Security Deposit''
AND mtx2.TYPE = ''Payment Component''
AND mtx2.depends_on = ''ACCESS LEVEL''
AND mtx1.order_type = ''';
A simplified version of what you're seeing, with a dummy table and simple anonymous block:
create table t42 (id number, some_value varchar2(10));
declare
type t_rec is record(id number, some_value varchar2(10));
l_rec t_rec;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
PL/SQL procedure successfully completed.
To get the error you're seeing I just need to remove one of the table columns:
alter table t42 drop column some_value;
and run exactly the same code again:
declare
type t_rec is record(id number, some_value varchar2(10));
l_rec t_rec;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
ORA-01007: variable not in select list
ORA-06512: at line 10
The field list in the record type declared in the PL/SQL block no longer matches the column type in the cursor query. The record variable you're fetching into expects two columns (in my version; 22 in yours), but the query only gets one value.
You can (some would say should) specify all the columns you're selecting explicitly, but assuming you're actually referring to them all later you would then have done the equivalent of:
open l_cur for 'select id, some_value from t42';
which would still have errored after the column removal, though a bit more helpfully perhaps:
ORA-00904: "SOME_VALUE": invalid identifier
ORA-06512: at line 9
Since you're currently intending to get all columns from a single table, you could also have used the %rowtype syntax instead of your own record type:
declare
l_rec t42%rowtype;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
which with this trivial example runs successfully. You'll still have a problem though as soon as you refer to the removed column, assuming it's still part of the record:
declare
l_rec t42%rowtype;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
dbms_output.put_line(l_rec.some_value);
close l_cur;
end;
/
ORA-06550: line 7, column 30:
PLS-00302: component 'SOME_VALUE' must be declared
ORA-06550: line 7, column 3:
PL/SQL: Statement ignored
(Using %rowtype would give you some breathing space if a column was added, as it would just be ignored, unless and until you added code to refer to that record field. But with your code you'd get ORA-00932 inconsistent data types, rather than ORA-01007, so that doesn't seem to be what's happening here.)
If you aren't referring to the removed column/field anywhere then you shouldn't be selecting it anyway. Change the record type to only include the fields you actually need, and only get the corresponding columns in the cursor query.
If you are referring to the removed column/field then you're stuck anyway - you'll have find out what was removed and why, and then either fix your code to not refer to it (if that makes sense), or get that change reverted.

oracle procedure error PLS-00103 Encountered the symbol "END" [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
I get the following error:
58/6 PLS-00103: Encountered the symbol "END" when expecting one of
the following:
begin function pragma procedure subtype type
current cursor delete
exists prior
Anyone have any idea what I am missing?
CREATE OR REPLACE PROCEDURE VALIDATE_BI_JOB_COMPLETE_PROC AS
msg SYS.XMLTYPE;
msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;
msg_id RAW(16);
queue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
rec_count INTEGER;
/******************************************************************************
NAME: VALIDATE_BI_JOB_COMPLETE_PROC
*******************************************************************************
BEGIN
INSERT INTO JOB_LOG
(JOB_NAME, JOB_SEQUENCE, RUN_DATE, LINE_SEQ_NO, LOG_TXT)
VALUES
($$PLSQL_UNIT, 1, SYSDATE, 1, 'Job Started at ' || to_char(sysdate, 'MM/DD/YYYY HH:MI:SS'));
COMMIT;
rec_count := 0;
SELECT COUNT(*) INTO rec_count
FROM SCHEDULED_JOBS
WHERE JOB_NAME IN ('bi_get_transactional_data', 'bi_get_reference_data') AND
CURRENTLY_PROCESSING_FLG = 'Y';
IF rec_count > 0 THEN
BEGIN
DECLARE CURSOR email IS
SELECT EMAIL_ID
FROM ERROR_EMAIL_NOTIFICATION
WHERE ACTIVE = 'Y' AND
SEVERITY_CD = 'ERROR';
vFROM VARCHAR2(30) := 'WORK_SYSTEM#XXX.COM';
vTYPE VARCHAR2(30) := 'text/plain; charset=us-ascii';
msg_body VARCHAR2(4000) := 'BI jobs are still running, please investigate.
bi_get_transactional_data, bi_get_reference_data)';
crlf CONSTANT VARCHAR2(2):= CHR(13) || CHR(10);
FOR email_rec IN email
LOOP
utl_mail.send(vFROM, email_rec.EMAIL_ID, NULL, NULL, ora_database_name || ': ' ,
msg_body, vTYPE, NULL);
END LOOP;
END;
END IF;
INSERT INTO JOB_LOG
(JOB_NAME, JOB_SEQUENCE, RUN_DATE, LINE_SEQ_NO, LOG_TXT)
VALUES
($$PLSQL_UNIT, 2, SYSDATE, 1, 'Job Ended at ' || to_char(sysdate, 'MM/DD/YYYY HH:MI:SS') ||
'. Records sent to JSSO: ' || rec_processed);
COMMIT;
-- exception processing goes here
EXCEPTION
WHEN OTHERS THEN
LOG_ERROR(
p_APP_ID => 'ORACLE',
p_SEVERITY_CD => 'ERROR',
p_ROUTINE_NAME => $$PLSQL_UNIT,
p_BACKTRACE => DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,
p_SQL_CODE => SQLCODE,
p_LOG_TXT => SQLERRM,
p_HOST_ID => SYS_CONTEXT('userenv', 'host'),
p_USER_ID => SYS_CONTEXT('userenv', 'session_user'),
p_SESSION_ID => SYS_CONTEXT('userenv', 'sid'));
INSERT INTO JOB_LOG
(JOB_NAME, JOB_SEQUENCE, RUN_DATE, LINE_SEQ_NO, LOG_TXT)
VALUES
($$PLSQL_UNIT, 2, SYSDATE, 1, 'Job ABENDED at ' || to_char(sysdate, 'MM/DD/YYYY
HH:MI:SS') || '. Error condtion.');
COMMIT;
END;
/
You must move your BEGIN from the 28 line to the line 41. Instead of this:
IF rec_count > 0 THEN
BEGIN <----------------------------------------- THIS IS WRONG
DECLARE CURSOR email IS
SELECT EMAIL_ID
FROM ERROR_EMAIL_NOTIFICATION
WHERE ACTIVE = 'Y' AND
SEVERITY_CD = 'ERROR';
vFROM VARCHAR2(30) := 'WORK_SYSTEM#XXX.COM';
vTYPE VARCHAR2(30) := 'text/plain; charset=us-ascii';
msg_body VARCHAR2(4000) := 'BI jobs are still running, please investigate.
bi_get_transactional_data, bi_get_reference_data)';
crlf CONSTANT VARCHAR2(2):= CHR(13) || CHR(10);
FOR email_rec IN email
LOOP
Write this:
IF rec_count > 0 THEN
DECLARE CURSOR email IS
SELECT EMAIL_ID
FROM ERROR_EMAIL_NOTIFICATION
WHERE ACTIVE = 'Y' AND
SEVERITY_CD = 'ERROR';
vFROM VARCHAR2(30) := 'WORK_SYSTEM#XXX.COM';
vTYPE VARCHAR2(30) := 'text/plain; charset=us-ascii';
msg_body VARCHAR2(4000) := 'BI jobs are still running, please investigate.
bi_get_transactional_data, bi_get_reference_data)';
crlf CONSTANT VARCHAR2(2):= CHR(13) || CHR(10);
BEGIN <-------------------------------------------- THIS IS OK
FOR email_rec IN email
LOOP
You have an END; just before your END IF; which is causing the problem
So Oracle thinks the IF statement is not closed. Plus it will ignore all the code after the END!
IF rec_count > 0 THEN
BEGIN
DECLARE
CURSOR email IS
SELECT EMAIL_ID
FROM ERROR_EMAIL_NOTIFICATION
WHERE ACTIVE = 'Y' AND
SEVERITY_CD = 'ERROR';
vFROM VARCHAR2(30) := 'WORK_SYSTEM#XXX.COM';
vTYPE VARCHAR2(30) := 'text/plain; charset=us-ascii';
msg_body VARCHAR2(4000) := 'BI jobs are still running, please investigate.
bi_get_transactional_data, bi_get_reference_data)';
crlf CONSTANT VARCHAR2(2):= CHR(13) || CHR(10);
BEGIN
FOR email_rec IN email
LOOP
utl_mail.send(vFROM, email_rec.EMAIL_ID, NULL, NULL, ora_database_name || ': ' ,
msg_body, vTYPE, NULL);
END LOOP;
END;
END;
END IF;
--rest of the code
The problem was that, after the 'DECLARE' you need to add a 'BEGIN', and an 'END' following the 'END LOOP'. I hope you understood. Also that makes me wonder, do you need the 'BEGIN' you have added just above the 'DECLARE' there? Hope this solves it :)

Resources