error PLSQL creating procedure with exception - oracle

I'm trying to create a procedure in PL/SQL and I receive the following error:
Errors: PROCEDURE BORRAR_PELI
Line/Col: 10/1 PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
( begin case declare end 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
json_exists json_value json_query json_object json_array***
My procedure:
CREATE OR REPLACE PROCEDURE borrar_peli(delete_id peliculas.id%TYPE)
IS
corrupto EXCEPTION;
precio_dia_v peliculas.precio_dia%TYPE;
BEGIN
SELECT precio_dia INTO precio_dia_v FROM peliculas WHERE id = delete_id;
IF precio_dia_v > 4 THEN
RAISE corrupto;
ELSE
DELETE FROM pelĂ­culas WHERE id = delete_id;
COMMIT;
END IF;
EXCEPTION
WHEN corrupto THEN
DBMS_OUTPUT.put_line('es corrupto');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Error code ' || SQLCODE || ': ' || SQLCODE);
END;

Related

Handling ORA-01403: no data found

I want to handle no data found. Whenever this exception is raised I want the program to continue, without stopping on error. Below is code snippet
BEGIN
OPEN C_TABLE_PARTITON_LIST;
LOOP
FETCH C_TABLE_PARTITON_LIST INTO TABLE_PARTITION_LIST;
EXIT WHEN C_TABLE_PARTITON_LIST%NOTFOUND;
SELECT COLUMN_NAME INTO PARTITION_COLUMN_NAME from ALL_PART_KEY_COLUMNS
sqlstring :='SELECT ( '|| PARTITION_COLUMN_NAME ||'from test';
EXECUTE IMMEDIATE sqlstring INTO F_RESULT;
exception when no_data_found then
dbms_output.put_line('no data found.');
DBMS_OUTPUT.put_line( F_RESULT);
END LOOP;
CLOSE C_TABLE_PARTITON_LIST;
END;
When I add Exception, my code is breaking with below error
PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
( begin case declare end exit for goto if loop mod null
pragma raise return select update while with
<<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
json_exists json_value json_query json_object json_array
ORA-06550: line 29, column 3:
PLS-00103: Encountered the symbol "CLOSE" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
You have to enclose offending part of the script into its own BEGIN-EXCEPTION-END block, e.g.
BEGIN
OPEN C_TABLE_PARTITON_LIST;
LOOP
FETCH C_TABLE_PARTITON_LIST INTO TABLE_PARTITION_LIST;
EXIT WHEN C_TABLE_PARTITON_LIST%NOTFOUND;
begin --> you need this ...
SELECT COLUMN_NAME INTO PARTITION_COLUMN_NAME from ALL_PART_KEY_COLUMNS
sqlstring :='SELECT ( '|| PARTITION_COLUMN_NAME ||'from test';
EXECUTE IMMEDIATE sqlstring INTO F_RESULT;
exception when no_data_found then
dbms_output.put_line('no data found.');
DBMS_OUTPUT.put_line( F_RESULT);
end; --> ... and this
END LOOP;
CLOSE C_TABLE_PARTITON_LIST;
END;
Note that I just showed the way to do that. Code you posted
is incomplete (misses the DECLARE section)
is invalid (SELECT statement lacks semi-colon, and probably a WHERE clause
SQLSTRING variable won't work; 'from test' should have a leading space, otherwise that statement will be invalid
I suggest you first DBMS_OUTPUT the SQLSTRING to make sure it is correct; then execute it.

Running PLSQL ( Oracle ) Stored Procedure in Liquibase error : Package or function X is in an invalid state

I am trying to run the following stored procedure:
CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION
AS
BEGIN
FOR i IN 1..5 LOOP
DBMS_OUTPUT.PUT('Try #' || i);
ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL;
END;
END;
/
and calling it in changelog.xml as:
<sql>CALL RETRY_TRANS_EXCEPTION();</sql>
i get error:
Liquibase update Failed: Migration failed for change set eldata-changelog.xml::2016-08-25-cn-01::Ch Will:Reason: liquibase.exception.DatabaseException: Error executing SQL CALL RETRY_TRANS_EXCEPTION(): ORA-06575: Package or function RETRY_TRANS_EXCEPTION is in an invalid state
What i am trying to achieve is to be able to run a stored procedure through Liquibase with a loop in it.
Thanks for your help Prashant. What worked in my case was your solution plus one change:
CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION
AS
v_query varchar2(100);
BEGIN
FOR i IN 1..500 LOOP
DBMS_OUTPUT.PUT('Try #' || i);
v_query := 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NULL';
execute immediate v_query;
END loop;
END;
/
and then calling the Stored Procedure from the changelog, as:
<changeSet id="2016-08-25-cw-01" author="Ch Will">
<comment>
Testing retry logic on liquibase
</comment>
<sql>CALL RETRY_TRANS_EXCEPTION();</sql>
</changeSet>
You can't call it because the procedure does not compile correctly. Go back and fix the compilation errors, then try again.
Here are a couple of errors that stand out to me:
the for loop should end with end loop;, not end;
You can't have DDL statements directly in the code. You need dynamic SQL to execute a DDL statement from a procedure: execute immediate 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL';
Additional note: I don't understand why you are trying to execute the same DDL statement multiple times inside a loop. Obviously, you won't be able to add the same column with the same name over and over. You will get a runtime error.
SQL> CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION
2 AS
3 BEGIN
4 FOR i IN 1..5 LOOP
5 DBMS_OUTPUT.PUT('Try #' || i);
6 ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL;
7 END;
8 END;
9 /
Warning: Procedure created with compilation errors
SQL> show err
Errors for PROCEDURE PRASHANT-MISHRA.RETRY_TRANS_EXCEPTION:
LINE/COL ERROR
-------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6/4 PLS-00103: Encountered the symbol "ALTER" when expecting one of the following: ( begin case declare end 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
Did required fixes :
CREATE OR REPLACE PROCEDURE RETRY_TRANS_EXCEPTION
AS
v_query varchar2(100);
BEGIN
FOR i IN 1..5 LOOP
DBMS_OUTPUT.PUT('Try #' || i);
v_query := 'ALTER TABLE CIS_CASE ADD TEST01 varchar2(1) NOT NULL' ;
execute immediate v_query;
END loop;
END;
PLSQL stored procedure can't use DDL statements, like
alter table ...
so the
execute immediate ("...")
statement is required because in fact it creates an autonomous implicit transition that can't be rollbacked

Warning: Package Body created with compilation errors

Please check my package and procedures.
My package:
create or replace package transaction1 as
procedure enter_transaction(acc number, kind varchar2, amount number);
procedure apply_transaction;
end;
/
This is my body:
create or replace package body transaction1 as
procedure enter_transaction(acc in number, kind in varchar2, amount in number)
is
begin
end;
procedure apply_transaction
is
begin
end;
end;
/
What is the warning? Why?
If you see a warning: Errors: check compiler log
then run show errors command and you will see the error log :
7/5 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
14/5 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
In case of your package body Oracle complains because BEGIN END blocks don't contain any commands.
In Oracle the BEGIN-END block must contain at least one command. Could be NULL, if you don't want to run anything (and don't forget to place a semicolon after NULL command):
PROCEDURE ......
IS
BEGIN
NULL;
END;

PL/SQL IF loop not working in my package

I want to write my procedure as follows:
begin
if(condn1) then
statements;
end if ;
exception part
end ;
begin
if(condn2) then
statements;
end if ;
exception part
end ;
When I try to compile this package I get the following error:
LINE/COL ERROR
-------- -----------------------------------------------------------------
509/5 PLS-00103: Encountered the symbol "WHEN" when expecting one of
the following:
( begin case declare end exception 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
The symbol "case" was substituted for "WHEN" to continue.
545/10 PLS-00103: Encountered the symbol ";" when expecting one of the
following:
case
If you want to include several exception parts, you must include a whole block for each exception part you want. The block structure is:
DECLARE [Optional]
... [Optional]
BEGIN
...
EXCEPTION
WHEN ... THEN
...
END;
Thus, your code with 2 exception parts should be something similar to the following code:
DECLARE
your_variables;
BEGIN
BEGIN
IF condition_1 THEN
statements;
END IF;
EXCEPTION
WHEN your_exceptions_for_part_1 THEN
...
END;
BEGIN
IF condition_2 THEN
statements;
END IF;
EXCEPTION
WHEN your_exceptions_for_part_2 THEN
...
END;
EXCEPTION
WHEN common_exceptions THEN
...
END;

PLSQL - Error in associative array

Im trying to delete a set of tables and afterwards I want to recreate them using as select from. For couriousity I wanted to do this with an associative array. Unfortunately something is messed up, several errors appear and I can't find the reasons. This is the code:
DECLARE
TYPE t_tbl
IS
TABLE OF VARCHAR(100) INDEX BY VARCHAR2(100);
L_Tbl T_Tbl;
l_key VARCHAR2(100);
BEGIN
l_tbl('tableA') := 'table1';
l_tbl('tableB') := 'table2';
L_Tbl('tableC') := 'table3';
l_tbl('tableD') := 'table4';
l_key := l_tbl.first;
LOOP
BEGIN
EXIT WHEN L_Key IS NULL;
Dbms_Output.Put_Line('Dropping TABLE '|| L_Key ||);
EXECUTE Immediate 'DROP TABLE ' || L_Key;
dbms_output.put_line(l_key ||' '|| l_tbl(l_key));
-- Catch exception if table does not exist
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
Raise;
END IF;
EXECUTE IMMEDIATE 'create table schema1.' ||l_key||' as select * from schema2.'||l_tbl(l_key)||;
l_key := l_tbl.next(l_key);
END LOOP;
End;
END;
I get these errors:
ORA-06550: line 17, column 56:
PLS-00103: Encountered the symbol ")" when expecting one of the following:
( - + case mod new null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current max min prior sql stddev sum
variance execute forall merge time timestamp interval date
<a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternatively-quoted SQL
ORA-06550: line 26, column 102:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
( - + case mod new null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current max min prior sql stddev su
ORA-06550: line 29, column 6:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
loop
The symbol "loop" was substituted for ";" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Could someone give me a hint please? Thank you in advance!
You have some unterminated append operations || on lines:
Dbms_Output.Put_Line('Dropping TABLE '|| L_Key ||);
And
EXECUTE IMMEDIATE 'create table schema1.' ||l_key||' as select * from schema2.'||l_tbl(l_key)||;
Get rid of the || at the end.
Also the way you are using LOOP is incorrect. Refer example:
while elem is not null loop
dbms_output.put_line(elem || ': ' || var_assoc_varchar(elem));
elem := var_assoc_varchar.next(elem);
end loop;
Remove || at the end of the line in line 17 and line 25.
And also ending loop before ending the block begin....end. get begin before loop or get end before end loop.
l_key := l_tbl.next(l_key);
END LOOP;
END;

Resources