How to catch all exceptions in PL/SQL script? - plsql

Currently I'm writing an update script with error handling. A part of this script contains a call to a table that might not exists. So I'd like to catch the exception. However, when running the script in SQL Developer, it does not seem to catch the exception.
Script (simplified):
BEGIN
SELECT VersionNumber
FROM DbVersion;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line(SQLCODE);
END;
SQL Developer Script Output:
Error starting at line 2 in command:
BEGIN
SELECT VersionNumber
FROM DbVersion;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line(SQLCODE);
END;
Error report:
ORA-06550: line 3, column 10:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 2, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Why does it not simply display the error code? Thanks!

If You are using non-existing table - that's syntax error - plsql block is invalid, and cannot be run.
Exception handling works when the block is running.
If You need to use table that may not exists, use can use dynamic sql (execute immediate 'select ... from non_existing_table') to avoid compile errors.
Or check for table existance in all_tables view.

Related

Oracle Error: stored procedure parameters values not declared

Following is the procedure code snippet:
PRC_UPDATE
BEGIN
UPDATE EMP E SET E.NAME = 'X' WHERE E.E_ID = 'Y';
COMMIT;
EXCEPTION WHEN OTHERS
ROLLBACK;
PRC_ERROR_LOG(E.E_ID,sqlcode,sqlerrm);
RAISE;
END PRC_UPDATE;
I have a procedure which updates the values in a table.I have defined an error logging procedure (PRC_ERROR_LOG)to insert the errors in an Error Logging Table.But while calling PRC_ERROR_LOG it throws an error as "identifier 'E_ID' must be declared". Will it not recognize the Row value in which the error is thrown out.
Basically my requirement is to insert the error and the row where the particular error is caught into the error table .How can I send the particular Row value in the Error Logging Procedure?
Thanks in advance
You should look into using a cursor, the reason that you are experiencing this error is that you have already executed the update statement and the e.e_id is now out of scope. You could also use try-catch to accomplish this.

plsql Trigger error ORA-00604

Following Trigger created in a user anu
create or replace trigger audit_creation1
before create
on schema
begin
insert into audit_creation
values(audit_creation_s1.nextval,
ora_dict_obj_owner,
ora_dict_obj_name,
sysdate);
end;
create table cc(cid number);
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
This worked before many times. It was working successfully.
But now it's throwing error.
Throw a command
purge recyclebin;
as your trigger owner (anu in your case).

SQL - PL/SQL Writing a basic function and running it to query a result

I have the table 'Company' populated with multiple tuples/rows. One of which is Microsoft for the 'Company_name' field and the 'City' field is populated as Redmond.
I have compiled this PL/SQL file.
-- Create a function that will return the city where company X is located.
-- X will be the parameter supplied by the caller.
-- Test your function with the company of your choice.
CREATE OR REPLACE FUNCTION company_location_city(x IN company.company_name%TYPE)
return company.city%TYPE IS
company_location company.city%TYPE;
BEGIN
select city into company_location
from company
where company_name = x;
return company_location;
END;
and ran it with this line.
select company_location_city('Microsoft') from dual;
I get this error, and I don't understand what it is trying to tell me. Of course we encountered select.
I am running the Oracle flavor.
Error(12,1): PLS-00103: Encountered the symbol "SELECT"
Also the query result showing an error should help.
ORA-06575: Package or function COMPANY_LOCATION_CITY is in an invalid state
06575. 00000 - "Package or function %s is in an invalid state"
*Cause: A SQL statement references a PL/SQL function that is in an
invalid state. Oracle attempted to compile the function, but
detected errors.
*Action: Check the SQL statement and the PL/SQL function for syntax
errors or incorrectly assigned, or missing, privileges for a
referenced object.
Error at Line: 16 Column: 8
The PLS prefix of the error says that it is pl\sql engine error. Hence it means that your sql code was treated as pl\sql because of the function ddl code which is pl\sql. You mixed up sql and pl/sql , you should split them by delimiter or remove one of the types of code.

oracle execute immediate not executing

I am new to Oracle (11gr2) and I have the following script:
BEGIN
DECLARE
source varchar2(1);
BEGIN
dbms_output.enable;
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW SP_AD;';
SELECT SOURCE INTO source FROM map_switch WHERE ROWNUM = 1;
IF source = 'A'
THEN
EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B;';
EXECUTE IMMEDIATE 'RENAME TABLE SP_AD_A TO SP_AD;';
ELSE
EXECUTE IMMEDIATE 'DROP TABLE SP_AD_A;';
EXECUTE IMMEDIATE 'RENAME TABLE SP_AD_B TO SP_AD;';
END IF;
COMMIT WORK;
dbms_output.put_line('SP_AD table issue fixed');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Exception, rolling back transaction, SP_AD not resolved.');
ROLLBACK WORK;
END;
END;
END;
/
Essentially, its determining which table to drop, then it drops the view and renames the other table.
If I run the statements individually, it works perfectly well, but in the script above, it returns procedure executed successfully but nothing was executed.
I'm suspecting that its rolling back for some odd reason, but I'm hesitating to execute it without the rollback in place (these tables have in excess of 300,000 records).
Can someone tell me what's wrong and also, is there something wrong with my exception block?
As pointed out by commenters, there are a few reasons why your code isn't working as expected.
Firstly, don't use semicolons inside the strings that you pass to EXECUTE IMMEDIATE, as doing that will give you an ORA-00911 'invalid character' error:
SQL> BEGIN
2 EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B;';
3 END;
4 /
BEGIN
*
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at line 2
After running this, you can then verify that the table still exists:
SQL> SELECT * FROM SP_AD_B;
no rows selected
(I don't have your table SP_AD_B, so I just created one named SP_AD_B with a single integer column in it. I didn't bother putting any data in it.)
If you remove the semicolon inside the string, not the one outside, it works:
SQL> BEGIN
2 EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B';
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> SELECT * FROM SP_AD_B;
SELECT * FROM SP_AD_B
*
ERROR at line 1:
ORA-00942: table or view does not exist
Now that the table's gone, we get an error attempting to query it.
Hopefully, this should allow you to fix your script so that it works and drops the relevant tables.
But why weren't you getting any helpful information in your output message? Well, let's recreate the SP_AD_B table, and reintroduce the semicolon, and try dropping the table again, but with an EXCEPTION handler similar to yours:
SQL> BEGIN
2 EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B;';
3 EXCEPTION
4 WHEN OTHERS THEN
5 dbms_output.put_line('Exception, rolling back transaction, SP_AD not resolved.');
6 END;
7 /
Exception, rolling back transaction, SP_AD not resolved.
PL/SQL procedure successfully completed.
In this case, we got an error message telling us something went wrong, so the table wasn't dropped. But what went wrong? There are thousands of errors that Oracle can report, and it can be difficult to guess what the problem is without knowing the error message.
There are a number of approaches you can take here. Firstly, you could write the error message, in SQLERRM to dbms_output:
SQL> BEGIN
2 EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B;';
3 EXCEPTION
4 WHEN OTHERS THEN
5 dbms_output.put_line('Exception, rolling back transaction, SP_AD not resolved.');
6 dbms_output.put_line('Error message was: ' || SQLERRM);
7 END;
8 /
Exception, rolling back transaction, SP_AD not resolved.
Error message was: ORA-00911: invalid character
PL/SQL procedure successfully completed.
You can also use dbms_utility.format_error_backtrace to return the current stacktrace as a string, if you so wish. That might help you figure out where the error came from.
Alternatively, you can reraise the exception. Using RAISE on its own in an EXCEPTION handler reraises the current exception:
SQL> BEGIN
2 EXECUTE IMMEDIATE 'DROP TABLE SP_AD_B;';
3 EXCEPTION
4 WHEN OTHERS THEN
5 dbms_output.put_line('Exception, rolling back transaction, SP_AD not resolved.');
6 RAISE;
7 END;
8 /
Exception, rolling back transaction, SP_AD not resolved.
BEGIN
*
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at line 6
However, given the fact that your EXCEPTION handler isn't really doing anything helpful, the best approach is quite probably to get rid of it altogether.
Your exception handler doesn't achieve anything because you can't commit or rollback DDL statements such as CREATE, ALTER, DROP or TRUNCATE. Each of these statements issues a COMMIT immediately before and after it runs. If a DROP succeeds but a RENAME fails, you can't get the dropped table back by rolling back a transaction. I'd recommend getting rid of your COMMIT WORK and ROLLBACK WORK statements.
Finally, commenter Jeffrey Kemp noticed this line:
SELECT SOURCE INTO source FROM map_switch WHERE ROWNUM = 1;
This assigns into a variable named source the value of the column SOURCE from some arbitrary row of the table map_switch. It could be any row; as you haven't specified any ordering, Oracle is free to order the rows of map_switch however it likes.
If there's only one row in the table, then it's clear which row you'll get back. However, if this is the case, why specify ROWNUM = 1? Does the table have more than one row and is the ROWNUM = 1 part is just there to silence an 'exact fetch returns more than requested number of rows' error?
You would be better off doing something like the following:
SELECT SOURCE INTO source
FROM (SELECT SOURCE FROM map_switch ORDER BY some_column)
WHERE ROWNUM = 1;
I don't know what columns there are in your map_switch table, so I've just used some_column above as a placeholder for one of them. Choose a column that has unique values, if possible.
Note that we can't simply do SELECT ... WHERE ROWNUM = 1 ORDER BY some_column as that would apply the ROWNUM = 1 clause before doing the sorting, and there's not a lot of point sorting a single row as there's only one order it can be returned in.

java.sql.SQLSyntaxErrorException: ORA-04098: trigger 'MYTABLE.MY_SEQUENCE_ID' is invalid and failed re-validation

I am creating this oracle 11g statement inside a java String and then executing it in sql developer. I tried running it on the database and got a warning when the trigger
is created. But, when run from the code, I get the error mentioned in my title.
Please tell me where is the mistake and how i can fix it ?
CREATE OR REPLACE TRIGGER myschema.my_sequence_id BEFORE INSERT ON myschema.mytable
FOR EACH ROW BEGIN SELECT my_sequence_id.nextval INTO :new.mycolumn FROM DUAL; end; /
Thanks in advance !
You can't have a trigger named my_sequence_id if you already have a sequence my_sequence_id. They share the same namespace. Your trigger would need to be named something other than the name of the sequence (or any other object in the schema).

Resources