PLSQL Error in apex when compiling the following code- PLS-00103 - plsql

I just referred to similar post related to same ORA & PLS error I faced, but still I can't resolve it using provided solution.
I get the following error: PLS-00103: Encountered the symbol “end-of-file” when expecting one of the following: begin function pragma procedure
My code:
create package PACHET is
procedure adaugaAngajat (v_id angajati.id_ang%type, v_idL angajati.id_lab%type, v_numeP angajati.nume%type, v_prenume angajati.prenume%type, v_ore angajati.ore_lucrate%type, v_sal angajati.salariul%type, v_dat angajati.data_angajare%type, v_tel angajati.telefon%type, v_post angajati.postocupat%type );
procedure modificaAngajat(v_id angajati.id_ang%type, v_idL angajati.id_lab%type, v_numeP angajati.nume%type, v_prenume angajati.prenume%type, v_ore angajati.ore_lucrate%type, v_sal angajati.salariul%type, v_dat angajati.data_angajare%type, v_tel angajati.telefon%type, v_post angajati.postocupat%type );
function verifica_telefon(v_tel angajati.telefon%type)
return boolean;
exp1 exception;
end;
create or replace package body PACHET is
procedure adaugaAngajat (v_id angajati.id_ang%type, v_idL angajati.id_lab%type, v_numeP angajati.nume%type, v_prenume angajati.prenume%type, v_ore angajati.ore_lucrate%type, v_sal angajati.salariul%type, v_dat angajati.data_angajare%type, v_tel angajati.telefon%type, v_post angajati.postocupat%type)
is
begin
if ( verifica_telefon(v_tel))
then
raise exp1;
else
insert into angajati values (v_id, v_idL, v_numeP, v_prenume, v_ore, v_sal, v_dat, v_tel, v_post);
end if;
exception
when exp1 then
dbms_output.put_line('Exista deja acest angajat!');
end;

As you tagged the question with Oracle Apex, I presume you're trying to create that package in its SQL Workshop. Of so, it can't execute more than a single statement at a time.
Therefore, put only package specification into the editor and run it. Then delete it and put package body into the editor and run that piece of code.
Alternatively, select (paint it blue) package spec statement and run it; then deselect it and select package body instead to run that statement.

PLS-00103, In short, this error means you have done some syntax error in your pl/SQL code, adding syntax that we should follow
--Firstly creating a declaration of a package
CREATE OR REPLACE PACKAGE PACHET
IS
PROCEDURE EXAMPLE(...);
.
.
END PACHET;
/
I think you have not ended the package and that is causing an error if I am not wrong or you have not pasted your full code, also you can add the name of the procedure or package with the end statements that would make it easy to follow the code.
Also first define the package(specs) and then run the body part.
create or replace package body PACHET is
procedure adaugaAngajat (v_id angajati.id_ang%type, v_idL angajati.id_lab%type, v_numeP angajati.nume%type, v_prenume angajati.prenume%type, v_ore angajati.ore_lucrate%type, v_sal angajati.salariul%type, v_dat angajati.data_angajare%type, v_tel angajati.telefon%type, v_post angajati.postocupat%type)
is
begin
if ( verifica_telefon(v_tel))
then
raise exp1;
else insert into angajati values (v_id, v_idL, v_numeP, v_prenume, v_ore, v_sal, v_dat, v_tel, v_post);
end if;
exception
when exp1 then
dbms_output.put_line('Exista deja acest angajat!');
end adaugaAngajat;
end PACHET;
/

Related

Plsql Package errors

The below code is getting many errors. Just want to check if my code syntax is correct. The main logic behind the package is to get all the cases for particular review and spool it to a file using shell script. As of now, am concentrating on the package .
create or replace PACKAGE BODY PK_FCP_EXTRACT is
PROCEDURE sp_fcp_extract is
cursor Rev_cur is select * from t_uar_reviews where CREATED_DATE=trunc(sysdate) ;
r Rev_cur%rowtype;
cursor case_cur( c_revid IN t_uar_reviews.review_id%type )
is select *
from t_uar_cases where review_id= c_revid ;
c case_cur%rowtype;
begin
open Rev_cur;
loop
fetch Rev_cur into r;
exit when Rev_cur%notfound;
open case_cur( r.review_id );
loop
fetch case_cur into c;
exit when case_cur%notfound;
dbms_output.put_line(c.UAR_CASE_ID||','||c.UAR_REVIEW_ID||','||c.CASE_TYPE||','||c.CASE_NMBR||','||c.ACTIVE_FLAG||','|| c.CREATED_DATE);
end loop;
close case_cur;
end loop;
close Rev_cur;
end;
END PK_FCP_EXTRACT;
Your syntax is correct.
The following test code works correctly in an empty schema:
create table t_uar_reviews(
review_id number,
created_date date
)
/
create table t_uar_cases(
review_id number,
UAR_CASE_ID number,
UAR_REVIEW_ID number,
CASE_TYPE varchar2(10),
CASE_NMBR number,
active_flag varchar2(1),
created_date date)
/
create package PK_FCP_EXTRACT is
PROCEDURE sp_fcp_extract;
end;
/
create or replace PACKAGE BODY PK_FCP_EXTRACT is
PROCEDURE sp_fcp_extract is
cursor Rev_cur is select * from t_uar_reviews where CREATED_DATE=trunc(sysdate) ;
r Rev_cur%rowtype;
cursor case_cur( c_revid IN t_uar_reviews.review_id%type )
is select *
from t_uar_cases where review_id= c_revid ;
c case_cur%rowtype;
begin
open Rev_cur;
loop
fetch Rev_cur into r;
exit when Rev_cur%notfound;
open case_cur( r.review_id );
loop
fetch case_cur into c;
exit when case_cur%notfound;
dbms_output.put_line(c.UAR_CASE_ID||','||c.UAR_REVIEW_ID||','||c.CASE_TYPE||','||c.CASE_NMBR||','||c.ACTIVE_FLAG||','|| c.CREATED_DATE);
end loop;
close case_cur;
end loop;
close Rev_cur;
end;
END PK_FCP_EXTRACT;
Possible causes of trouble:
Make sure that the package spec has been created first (CREATE PACKAGE)
Ensure that the package is created in the schema that owns t_uar_reviews and t_uar_cases, or in a schema that has a direct SELECT grant on the tables (not via a role).
Make sure all of the columns you reference in the package exist in the tables.
If those are all done, it should work.
To simplify things, try using this alternate syntax for your cursor loops:
for r in Rev_cur loop
for c in Case_cur(r.review_id) loop
...do something..
end loop;
end loop;
By using this method, you do not need to define the record r or c; they are implicitly created, and you do not to open/fetch/check/close the cursors.

How to remove extra information form error message after executing a package body?

I want to remove extra information form error message after executing a package body.
Example:
If I run a anonymous block then the error message come like -
ERROR at line 1:
ORA-20010: Object ID PE556092 is not Produced by the Template TP000036
ORA-06512: at "EXAMPLE.TESTPROC", line 5
ORA-06512: at line 1
But i want to show only the below error message:
ORA-20010: Object ID PE556092 is not Produced by the Template TP000036
You can use the below to get the Error Code and Message respectively:
dbms_output.put_line('Error code: '||sqlcode);
dbms_output.put_line('Error msg: '||sqlerrm);
Read more about SQLERRM.
You can do that by defining an exception and mapping it to the SQLCODE of the raised error. Then you handle the logic in the exception handler.
Example, here I map to error -20010 (the one you are using):
declare
err_obj_not_produced exception;
pragma exception_init (err_obj_not_produced, -20010);
l_object varchar2 (50);
l_template varchar2 (50);
begin
run_your_code ('With values');
exception
when err_obj_not_produced then
return 'Object ID ' || l_object || ' is not Produced by the Template ' || l_template;
end;
Another one way to hide information about previous errors. Suppose you have two procedures:
create or replace procedure proc1 is
begin
raise no_data_found;
end;
/
create or replace procedure proc2 is
begin
proc1;
exception
when no_data_found then
raise_application_error(-20010, 'There is no spoon, Neo.');
end;
/
when you run a block in SQL*Plus, you get:
SQL> begin
proc2;
end;
/
begin
*
ERROR at line 1:
ORA-20010: There is no spoon, Neo.
ORA-06512: at "DEV.PROC2", line 6
ORA-06512: at line 2
You can change proc2 like this:
create or replace procedure proc2 is
begin
proc1;
end;
/
And call it like this with desired result:
SQL> begin
begin
proc2;
exception
when no_data_found then
raise_application_error(-20010, 'There is no spoon, Neo.', false);
end;
exception
when others then
dbms_output.put_line(SQLERRM);
end;
/
ORA-20010: There is no spoon, Neo.
PL/SQL procedure successfully completed.
This example shows how third parameter of raise_application_error procedure works. If you pass false, procedure deletes information about previously raised exceptions from error stack. It also will be impossible to get this information using dbms_utility.format_error_backtrace.
As Jon Heller noticed in comments, hiding information about exceptions is a bad practice (and using when others then without raise too, as Jeffry Kemp noticed), so, I hope you know what you are doing. This way or another, it is a shooting yourself in the foot.

PLS-00103 on package body

I've created a Package spec and body and when I execute the script I get no errors. However my package body stays in invalid state. I can't understand why, can you please help?
Here's my code:
CREATE OR REPLACE PACKAGE BODY CONFIG_MODULE_API AS
FUNCTION APPLY_RULES(I_EVENT_ROWID IN VARCHAR2,
I_EVENT_TABLE_NAME IN VARCHAR2,
I_EVENT_OPERATION IN VARCHAR2,
O_EVENT_STAGE OUT CFG_EVENT_STAGE,
O_STATUS_CODE OUT VARCHAR,
O_ERROR_MSG OUT VARCHAR) RETURN BOOLEAN IS
BEGIN
--no code yet
RETURN NULL;
END APPLY_RULES;
PROCEDURE TEST_RULES(I_FILTER_ID NUMBER,
I_EVENT_TABLE_NAME VARCHAR2,
O_SQL_STMT OUT VARCHAR,
O_STATUS_CODE OUT VARCHAR,
O_ERROR_MSG OUT VARCHAR) IS
BEGIN
--no code yet
END TEST_RULES;
END CONFIG_MODULE_API;
And here's the exception I get whenever I check the stack trace:
Compilation errors for PACKAGE BODY MYSHCEMA.CONFIG_MODULE_API
Error: PLS-00103: Encountered the symbol "END" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
Line: 20
Text: END TEST_RULES;
What am I missing?
(My package spec, works fine.)
You need a null statement after the BEGIN and before the END TEST_RULES (where it says no code yet.
BEGIN
NULL;
END TEST_RULES;

ORA-00905: missing keyword in SQL PLus

I am getting an ORA-00905: missing keyword error when running in the following procedure using the SQLPLUS command line. Strangely it compiles and works when I run it in via an SQL window in PL/SQL developer, unfortunately I need it to work via the command line as well:
CREATE OR REPLACE PROCEDURE PRO_INSERT_ALERT_END_DATE IS
CURSOR cur_InsertEndDate IS
SELECT cli_per_id,
date_ended,
date_started,
alertid
FROM CP_END_ALERT;
BEGIN
FOR rec_cur_InsertEndDate IN cur_InsertEndDate
LOOP
BEGIN
UPDATE vwe_alert_table
SET alert_inactive_on = rec_cur_InsertEndDate.date_ended,
alert_inac_reason = 'Deregistered'
WHERE vwe_alert_table.art_id = rec_cur_InsertEndDate.alertid AND
vwe_alert_table.art_per_id = rec_cur_InsertEndDate.cli_per_id AND
vwe_alert_table.art_alerted_on = rec_cur_InsertEndDate.date_started AND
vwe_alert_table.art_alert = 'AL02';
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error updating record ' || SUBSTR(SQLERRM, 1, 250));
ROLLBACK;
END;
END LOOP;
END PRO_INSERT_ALERT_END_DATE;
Any advice would be most welcome
It is probably due to the blank lines in the script. Tell SqlPlus to ignore them
set sqlblanklines on

Oracle 11g PL/SQL Positions of CONTANT variables in PACKAGE

I have strictly optimization problem. where in my PACKAGE I should place CONSTANT variables when procedure/function is being called many times ?
Let's look at this:
CREATE OR REPLACE PACKAGE WB_TEST IS
PROCEDURE TEST;
END WB_TEST;
CREATE OR REPLACE PACKAGE BODY WB_TEST IS
FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
LC_MSG CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
LC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';
BEGIN
RETURN REPLACE(LC_MSG, LC_PARAM, IN_PARAM);
END PARSER;
PROCEDURE TEST IS
BEGIN
FOR I IN 1 .. 1000 LOOP
DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
END LOOP;
END TEST;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
/
Or is better to do something like that:
CREATE OR REPLACE PACKAGE WB_TEST IS
PROCEDURE TEST;
END WB_TEST;
CREATE OR REPLACE PACKAGE BODY WB_TEST IS
GC_MSG CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
GC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';
FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN REPLACE(GC_MSG, GC_PARAM, IN_PARAM);
END PARSER;
PROCEDURE TEST IS
BEGIN
FOR I IN 1 .. 1000 LOOP
DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
END LOOP;
END TEST;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
It is extremely unlikely to matter from a performance standpoint. The code the PL/SQL compiler generates should be identical in both cases-- the constants will almost certainly get compiled inline where they are referenced.
The only reason to prefer one over the other would be code clarity and variable scoping. If the constants are really local to the PARSER function-- if they aren't likely to be useful to other methods in the package, they ought to be declared as part of the function. If, on the other hand, they are likely to be useful to other methods in the package, they ought to be declared as part of the package body. If they are likely to be useful to methods outside the package, they ought to be declared as part of the package specification.

Resources