I would like to ask is it possible to catch syntax errors on exception block ? Example I've below exception in my code, when it hit exception it would notify me via email. I know syntax errors is during compilation, so it won't execute exception block, but is it possible to catch it ?
EXCEPTION
WHEN OTHERS
THEN
SEND EMAIL
The procedure wont be compiled if there are syntax error.
in order to catch exception the Procedure should be compiled, if there are errors then you have to fix them.
However you can create a procedure that run your procedure(as a string, dynamically), if your second procedure contain error , even syntax error , you can catch it and insert it into table.
Check this link for more info
other way you can also write a program which can check invalid objects and send mail to you with object names.
here is sql to check invalid objects.
select * from all_objects where object_type in
('PACKAGE','PACKAGE BODY', 'PROCEDURE','FUNCTION') and status ='INVALID'
for syntax error you need to use tool like toad, pl/sql developer, sql developer etc. to show errors.
Related
I am trying to create function in oracle 12c database using liquibase, below is the sql formatted changelog. I am doing negative testing to see what response i get, purposefully using wrong keyword returns
--liquibase formatted sql
--changeset your.name:1 failOnError:true
CREATE OR REPLACE FUNCTION get_tab1_count RETURNS NUMBER AS
l_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_count
FROM person3;
RETURN l_count;
END;
/
This change log gets updated successfully, but as expected in the database I have a function now which has compilation errors,
Compilation errors for FUNCTION GET_TAB1_COUNT
Error: PLS-00103: Encountered the symbol "RETURNS" when expecting one of the following:
( return compress compiled wrapped
my question is am i doing something wrong, that liquibase is giving a "update has been successful" message? Or is this expected behaviour? I have tried adding failOnError:true in the changelog to see if it will actually now fail as there is a compilation error during function creation, but it does not make any difference. I would think that, liquibase would give some sort of failure message when there is a compilation error like the above, am I wrong?
Liquibase is just running your changeset as sql being passed to a JDBC connection.
quoting a colleague: "the jdbc connection gives us for a response and I THINK most databases are just "yes, you created that fine" even though it is not actually valid at this point. But, they don't tell us until we run it"
As a work around you could write a script that checks for compilation errors and fails when it finds any issues. Create an execute change set with runAlways="true"
I'm running into a problem where I'm trying to grant execution on a package to another schema.
GRANT EXECUTE ON PP.PKG_PROF TO PPSERVICE;
Looks like Oracle attempts to recompile/revalidate the package before making the grant. However it is failing with the following error:
GRANT EXECUTE ON PP.PKG_PROF TO PPSERVICE
Error report -
SQL Error: ORA-04045: errors during recompilation/revalidation of PP.PKG_PROF
ORA-20000: ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 83
04045. 00000 - "errors during recompilation/revalidation of %s.%s"
*Cause: This message indicates the object to which the following
errors apply. The errors occurred during implicit
recompilation/revalidation of the object.
*Action: Check the following errors for more information, and
make the necessary corrections to the object.
But if i look at the code on line 83, it executes the following query:
select 'x' into vtemp
from cust_field_vals
where cust_fields = vin_cust_fields
and userid = vin_user_id;
vin_cust_fields and vin_user_id are parameter based values that are provided when the procedure in the package gets called.
My question is: what in the world is oracle doing? I understand that a "SELECT INTO"
can theoretically return more than the requested number of rows (which would need to be one in this case), but since it doesn't know what my vin parameters are, how can it make that assessment? Why is a recompilation/revalidation throwing what essentially amounts to an exception for a data anomaly which it shouldn't even be looking at for what I'm trying to do (ie: i'm not trying to actually execute the procedure).
This is not the first time I've seen this, and if I remember correctly, I even think it's happened on recompilation of triggers as well (not when inserting data).
Any thoughts? Thanks!
apparently, the problem was the package i was trying to GRANT execute on was "invalid" even though there were no actual code errors. Compiling the body first was generating the above mentioned error. If I manually compiled the package spec first, then the body, the error went away and the grant executed normally. No code errors were present in the package, it was just stuck in an invalid state it could not get out of.
Is there any Oracle table, view , function or procedure or may be tool. For which sqlstate and/or sqlerror is input and it give detail of sqlstate and/or sqlerror. I can see sqlstate and sqlerror from http://docs.oracle.com/cd/E15817_01/appdev.111/b31228/appd.htm but I want from oracle by sql. So it is more reliable :
Thanks in advance
Ram
oerr - Oracle error messages, is a utility (script not an executable) which comes with unix and linux based oracle installations and can be found in the bin directory. Input to this script could be the error code.
this utility extracts error messages with suggested actions from the standard Oracle message files
Just because it uses awk functionalities, it is not supported in windows.
Usage details :
http://www.oracledistilled.com/oracle-database/troubleshooting/using-the-oerr-utility-to-aid-in-error-investigation/l
SQLERRM and SQLCODE functions extract error messages and error codes, but it returns value only inside the exception handler and not in any SQLs, outside them, it always return success message! So, I doubt your requirement via SQL will be ever possible!
I have a situation where the site I maintain calls a plsql package/procedure (Oracle 11g). The procedure builds a string of dynamic sql using the parameters passed in (call the string "v_select"). After the string is built, a ref cursor is opened using the v_select dynamic sql string. Pseudo code below.
OPEN ref_cursor FOR v_select
USING variables set to input parameters ;
Now, the procedure has an exception block (WHEN OTHERS) to catch any exceptions. In the exception block, any errors are written to a table in the DB. When an error occurs while the dynamic sql is executed, the error does not seem to be caught by the exception block (no entry is being inserted into the error table), but I can see the error at the .net level, so I know it's an Oracle invalid_number error.
So, finally, my question is this....from what I see online (which wasn't much), if the dynamic sql chokes, this should be caught by the exception block. Is this correct?
This error usually isn't detected until the query actually executes, which may not happen until you try to fetch the first row from the cursor. The generated SQL is correct logically and syntactically; it's just doing a type conversion that is invalid for some of the rows in your database. So the error isn't caught in the stored procedure; when the stored procedure is done it hasn't happened yet.
This has nothing to do with the query being dynamic. A non-dynamic version of the same query would still not throw the error until you fetch from the cursor.
I need an example of creating error log file for stored procedure in oracle.
please give me an example with table creation and stored procedure creation and error log creation.
Thanks in advance
EDIT (relevant info from other question)
Suppose there is a stored procedure. When I am executing that stored procedure, some expected error/exception may occur, so I need to create an error log table in which all the errors will automatically be store whenever I will execute the stored procedure.
For example, if there is some column which does not allow null values, but the user is entering null values, then that error should be generated and it should stored in the error log table.
You haven't really given a lot of detail about your requirements. Here is a simple error log table and a procedure to log error messages into it:
CREATE TABLE error_log (ts TIMESTAMP NOT NULL, msg VARCHAR2(4000));
CREATE PROCEDURE log_error (msg IN VARCHAR2) IS
BEGIN
INSERT INTO error_log (ts, msg)
VALUES (SYSTIMESTAMP, SUBSTR(insert_log.msg, 1, 4000));
END log_error;
You might or might not need it to be an autonomous transaction. That would depend on whether you want the log to record errors from procedures that rollback their changes.
Typically, this will be implemented in a more generic logging system which would log not only errors, but warnings and debug info too.
If you want a DML statement (insert/update/delete) to log an error for each row (instead of just failing on the first row that errors), you can use the LOG ERRORS clause - instead of the statement failing, the statement will succeed, and the rows that were not inserted/updated/deleted will be written to the error log table you specify, along with the error code and error message applicable. Refer to the link provided by vettipayyan.
If you want all exceptions that are raised within a procedure to be logged, you can catch them with WHEN OTHERS:
BEGIN
-- your code here
EXCEPTION
WHEN OTHERS THEN
log_error(DBMS_UTILITY.format_error_stack);
log_error(DBMS_UTILITY.format_error_backtrace);
RAISE;
END;
Here's the page with code samles:
DML ErrorLogging