I am new to using SQL Profiler and have been using it to try and identify the source of an exception. It occurs during a trigger but does not appear to be caused by it. I have the Exception EventClass selected but I do not see any information as to where the exception was thrown from.
The exception occurs after a SELECT in the trigger that works successfully. I have inserted a RAISERROR after the select to log the parameters and return values from the select. They are all valid.
As I put more RAISERROR statements in, the exception moves further down within the trace.
I must be missing something in how to log the Exception in the profiler. I just cannot see where the exception is coming from so I can get to it and fix it.
The text of the exception is "Arithmetic overflow error converting expression to data type datetime."
Found it. Needed more events to properly encapsulate the exception in Profiler.
Related
In my batch job, I have a single step with reading from Database , processing the record and writing back the same record to same table.(ie updating record with processed values or error reason if processing failed).
I am using AsyncItemProcessor for multi thread processing. When I get error in ItemProcessor.process() method, I throw an exception and batch job ends with FAILED status. This failed status is a requirement.
Because, its AsyncItemProcessor, I am unable to access ItemProcessListener.onProcessError().
How do I write the errorMessage to Item Table when there is an error ?
This is a known limitation of using the AsyncItemProcessor which is mentioned in its Javadoc:
While not an exhaustive list, things like StepExecution.filterCount will not
reflect the number of filtered items and
ItemProcessListener.onProcessError(Object, Exception) will not be called.
There is an open issue to update the reference documentation as well.
How do I write the errorMessage to Item Table when there is an error ?
The AsyncItemProcessor submits a FutureTask to the task executor and the only way to know if an exception happened in the task is by unwrapping the future (the exception will be actually wrapped in a java.util.concurrent.ExecutionException when the FutureTask.get is called). Now since the future is unwrapped in the AsyncItemWriter, you can use an ItemWriteListener and react to processing errors. You can find a complete example here.
When an exception happens at the first select statement. Will the second select statement and the function then be executed in any case? Or will all following statements be skipped ?
BEGIN
SELECT ...
SELECT ...
procedure_that_performs_select();
EXCEPTION
WHEN NO_DATA_FOUND THEN ...
END
In PLSQL, the occurrence of an exception stops program exectuion at the point of the exception and jumps to the EXCEPTION block, if any, for handling, else raises the exception to the client.
You can see this behavior in a test block.
Here we will print before and after the exception, and can observe the next statement after the exception does not get printed:
BEGIN
DBMS_OUTPUT.PUT_LINE('About to throw an exception');
RAISE_APPLICATION_ERROR(-20001,'Exception');
DBMS_OUTPUT.PUT_LINE('Done throwing exception');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Handling the exception');
END;
/
Result:
About to throw an exception
Handling the exception
Note: in the example you provided, the EXCEPTION block only handles NO DATA FOUND exceptions, so other types of exceptions will be raised instead of running through the exception handler. But in any case, things will stop processing at the point of the exception.
Once the control goes to an exception block, it doesn't go back to the begin or declare section of the pl/sql block.
Following the same, if there is an error in your first select statement, the exception block will be executed and the respective handler would be used. In case, you have neither mentioned the respective handler nor a WHEN OTHERS, the control will go to the calling environment (either any procedure or interface/ IDE).
In case, you still wish to run the second select statement, you could write another pl/sql block in exception handler.
In an OTHERS exception block I'd like to display the type of exception.
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE( -- I want to display the type of exception here -- );
END;
I would prefer a robust exception block rather than a trivial EXCEPTION WHEN OTHERS THEN without any specific purpose. Always remember, you catch exception and then DO something about it. Else, you need to RE-RAISE it to give the handle back to the caller.
In your exception block, add the following :
DBMS_UTILITY. FORMAT_ERROR_STACK;
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
This will give you the error stack and the backtrace procedure will let you know the exactnline number of error. Since EXCEPTION takes the handle from the caller, thus the caller never comes to know about the error raised. Include RAISE statement to re-raise the error and give it back to the caller. Better have an error logging table to have the errors logged for future research.
And regarding when others, please read my article, http://lalitkumarb.wordpress.com/2014/05/02/when-others-then-null-a-bug/
declare
v number;
begin
select 1
into v
from dual
where 1=2;
exception
when others then
dbms_output.put_line('A');
when no_data_found then
dbms_output.put_line('B');
end;
On executing this I am getting an error but i had read it somewhere that in exception WHEN OTHERS, if placed first will always get executed suppressing other type of exceptions . I was asked this question in an interview and I as above . can somebody please confirm
You will get the following error in 11.2G:
Error at line 1
ORA-06550: line 11, column 3:
PLS-00370: OTHERS handler must be last among the exception handlers of a block
ORA-06550: line 0, column 0:
PL/SQL: Compilation unit analysis terminated
You should always have OTHER as the last exception handling block
The WHEN OTHERS clause is used to trap all remaining exceptions that have not been handled by your Named System Exceptions and Named Programmer-Defined Exceptions.
If you have only the WHEN OTHERS block in your code, then "PL/SQL procedure successfully completed." will be the message. Since the OTHER will never be encountered. A when others is almost always a BUG unless it is immediately followed by a RAISE. The point of an exception block is to catch exceptional conditions you are EXPECTING, handle them gracefully and continue. You should only catch the exceptions you are expecting and can do something about. Let the others propagate out so you can detect them (so you see them)
My suggestion would be "IGNORE WHEN OTHERS TOTALLY"
Executing this code block will raise the exception PLS-00370 (documented here):
PLS-00370: OTHERS handler must be last among the exception handlers of a block
Cause: One or more exception handlers appear after an OTHERS handler. However, the OTHERS handler must be the last handler in a
block or subprogram because it acts as the handler for all exceptions
not named specifically.
Action: Move the OTHERS handler so that it follows all specific exception handlers.
you just have to leave the OTHERS exception in the last place .
For instance:
BEGIN
something
EXCEPTION
THEN WHEN DUP_VAL_ON_INDEX
do something
WHEN OTHERS THEN
last exception do something
END;
I register my own vectored exception handler, to catch and trace various exceptions in my application.
Sometimes I get an exception having 0x40010006 code, which is thrown by OutputDebugString function. Certainly, I'd like just to ignore it. What would be the appropriate return value in this case: EXCEPTION_CONTINUE_EXECUTION or EXCEPTION_CONTINUE_SEARCH?
You'll find exception codes listed in the ntstatus.h SDK header file. This one is DBG_PRINTEXCEPTION_C, some likelihood that you typed Ctrl+C to trigger it.
Exception codes with values less than 0x80000000 are just informal and never an indicator of real trouble. In general, you should never mess with exceptions that you don't recognize and don't want to explicitly handle. Let Windows continue searching for a handler by returning EXCEPTION_CONTINUE_SEARCH, the debugger will probably catch it in this case.