Send error message via background job in oracle pl/sql - oracle

I need to send an error from a pl/sql script that I can log and monitor.
I try to create a procedure that does nothing but fail and display a custom defined error meassage.
PROCEDURE Custom_Error ()
BEGIN
raise_application_error(-20101, 'Custom Error!');
END Custom_Error;
I'm not allowed. I get this error:
Compilation errors for PACKAGE ...
Error: PLS-00103: Encountered the symbol ")" when expecting one of the following:
My plan was to call this procedure in the background, and then get the error 'Custom error' in my log of background jobs in error.
Is this the right way to go about this?
BR

Correct syntax for a parameterless procedure in PL/SQL
create or replace PROCEDURE Custom_Error is
BEGIN
raise_application_error(-20101, 'Custom Error!');
END Custom_Error;

Related

Catch PL/SQL error PLS-00306 iside PL/SQL method

I am running a method (the method name is sent by the end user) using dynamic PL/SQL (ex: EXECUTE IMMEDIATE).
When the method signature does not match the error ORA-06550 is raised (PLS-00306 is also mentioned in the stack).
I need to raise a custom message when the method signatures does not match with the required signature.
So I catch ORA-06550 inside the PL/SQL exception block and raise an error. Only to notice that ORA-06550 is raised for any invalid PL/SQL code (including method signature mismatch)
My Questions
What is the difference between ORA- type messages and PLS- types ones. Can't one catch PLS- type messages (ex: PLS-00306) like they do catch ORA- type ones (ex: ORA-06550). If possible how?
If not possible how to catch signature mismatches? (apart from running a query against USER_ARGUMENTS)
PLS-errors are PL/SQL compiler's compilation errors and can't be directly caught run-time as they are wrapped with ORA-errors.
If the compilation error is triggered by static PL/SQL the unit under compilation is created as invalid and execution of the unit triggers PLS-00905 (wrapped with ORA-06550).
If the compilation error is triggered by dynamic PL/SQL the unit under compilation is created without errors as dynamic PL/SQL is not checked during compilation. Instead the error is raised run-time when the unit is executed and can be caught but only ORA-code, not PLS-code. If you have do something based on PLS-code process the error stack string:
create or replace function get_custom_error(p_pls_code in varchar2) return varchar2 is
begin
return
case p_pls_code
when 'PLS-00201' then 'this is my custom error code'
else 'unknown PLS error code'
end;
end;
/
show errors
create or replace procedure foo is
plsql_compilation_error exception;
pragma exception_init(plsql_compilation_error, -6550);
v_a number;
begin
dbms_output.put_line('foo started');
execute immediate 'begin bar; end;';
dbms_output.put_line('foo ended normally');
exception
when plsql_compilation_error then
declare
v_pls_error_code constant varchar2(20) :=
regexp_substr(dbms_utility.format_error_stack,
'(PLS-[[:digit:]]+):', 1, 1, '', 1);
begin
dbms_output.put_line(get_custom_error(v_pls_error_code));
end;
end;
/
show errors
Execution example:
SQL> exec foo
foo started
this is my custom error code
PL/SQL procedure successfully completed.
SQL>
All Oracle error codes are listed and explained in Oracle Database Error Messages.
1) The difference between ORA and PLS is which engine raised the exception. Error on the top of error stack shows general error. Deeper errors provides more and more details. Like ORA-06550 happened because of PLS-00306
2) In any potentially dangerous place you should add BEGIN…EXCEPTION…END. To differentiate any ORA error you can declare exception in parent block and use PRAGMA directive to link it with error code.
begin
…
begin
…
execute immediate …
exception
when …
end;
…
end;

checking for specific error code in PL/SQL exception block

I am getting the ORA-06503: PL/SQL: Function returned without value error in a pl/sql trigger code. I actualy want to do some specific exception handling only if this error occurs else do the regular exception handling in my code.
My question is how do I capture the specific ORA codes in exception blocks. Like If I want to add a if condition like
If(oracode = something) then ...
else ...
the SQLERRM gives the ora code with error message. how do I use this in IF condition ?
Need help with this
Thanks.
You are looking for SQLCODE - these are negative numbers when there is an error.
if SQLCODE = -6503 then ....

DROP Oracle queue

I am trying to drop the queue using following command:
EXECUTE DBMS_AQADM.DROP_QUEUE (queue_name => 'ORDVAL_QUEUE');
It is working fine but i want to put a check if queue does not exist and i execute above command thn it should not throw an error or exception.
I m using this but din't got my target :
BEGIN
EXECUTE IMMEDIATE 'DBMS_AQADM.DROP_QUEUE (queue_name => "ORDVAL_QUEUE")';
EXCEPTION
WHEN OTHERS THEN
null;
END;
It executes fine but does not drop queue.
I haven't used queues before, but this should help:
Add a BEGIN and END to the execute immediate, to use dynamic PL/SQL instead of dynamic SQL.
Use two single quotes instead of a double quote.
Catch specific exceptions when possible, avoid OTHERS. This was catching and ignoring unexpected exceptions.
Not shown below, but perhaps it would be better to check for the existence of the queue in ALL_QUEUES instead?
DECLARE
QUEUE_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(QUEUE_DOES_NOT_EXIST, -24010);
BEGIN
EXECUTE IMMEDIATE
'BEGIN DBMS_AQADM.DROP_QUEUE (queue_name => ''ORDVAL_QUEUE''); END;';
EXCEPTION WHEN queue_does_not_exist then
dbms_output.put_line('Test to see if exception was thrown');
END;
/

formatting (or supplying string to) exception's messages in oracle

There are parameterized error messages in Oracle database. For example, there is 01919, 00000, "role '%s' does not exist" in oraus.msg.
If one issue some nonsense GRANT ... TO ... %s is substituted by this nonexistent privilege.
It is possible to raise exception -1919 and supply some string to %s?
Code:
not_system_privilege EXCEPTION;
PRAGMA EXCEPTION_INIT(not_system_privilege, -01919);
.......
RAISE not_system_privilege;
produces only ORA-01919: role '' does not exist message.
The purpose of user-defined exceptions is that we can trap specific exceptions in the exception section of our PL/SQL program and handle them elegantly. For instance, if we put some flesh around your code snippet....
create or replace grant_priv
( p_priv in varchar2
, p_grantee in varchar2 )
is
not_system_privilege EXCEPTION;
PRAGMA EXCEPTION_INIT(not_system_privilege, -01919);
begin
execute immediate 'grant '||p_priv||' to '||p_grantee;
exception
when not_system_privilege then
raise_application_error(-20000, p_priv||' is not a real privilege', true);
when others then
raise;
end;
We can put anything in the EXCEPTIONS section. Log the error in a table or file, raise alerts, whatever. It is good practice to propagate the exception upwards: only the toppermost layer of the callstack - the user-facing layer - shouldn't hurl exceptions.
An observation - it looks like you can use utl_lms.format_message for C-style printing - wish I'd known this earlier (as would have saved writing it). Seems to be Ora10 and above only.
begin
dbms_output.put_line(
utl_lms.format_message(
'A %s is here and a %s is there and a %s too','Giraffe','Lion','Spider'));
end;
I can't see any way to meet the OPs requirement - to RAISE a system-level exception and substitute in the right parameter.
However, if you can live with using a different exception number, you could write your own exception handling procedure that could
a) take in the serial of the required exception
b) use utl_lms.get_message to retrieve the text
c) use format_message to substitute in the parameters
d) raise a user defined exception using the generated text
The problem is that this would not work if your calling system expects an ORA-01919.

How do I execute private procedures in an Oracle package?

This is my first attempt at creating a package, so I must be missing something really really obvious (nothing that I've Googled for seems to even consider it worth mentioning).
Obviously, if you have procedures in your package body that are not included in the specification section, then those procedures are private. The problem I've got is that I can't seem to figure out how to reference those private packages once I've made them. And SQL Developer refuses to give me any message more useful than 'execution completed with warning', which doesn't help...
As an example, this is what I've been trying that doesn't work (just throws the aforementioned compiler error):
CREATE OR REPLACE PACKAGE BODY testPackage AS
PROCEDURE privateProc; --Forward declaration
PROCEDURE publicProc IS
BEGIN
EXECUTE privateProc();
END;
PROCEDURE privateProc IS
BEGIN
DBMS_OUTPUT.PUT_LINE('test');
END;
END testPackage;
I've also tried referring to it as testPackage.privateProc, which hasn't worked either.
What am I doing wrong?
I think you should do this:
CREATE OR REPLACE PACKAGE BODY testPackage AS
PROCEDURE privateProc; --Forward declaration
PROCEDURE publicProc IS
BEGIN
privateProc();
END;
PROCEDURE privateProc IS
BEGIN
DBMS_OUTPUT.PUT_LINE('test');
END;
END testPackage;
Just call privateProc as if it is part of the language. Execute is for running DML or SQL inside your PL/SQL.
CREATE OR REPLACE PACKAGE BODY testPackage AS
PROCEDURE publicProc; --Forward declaration
PROCEDURE publicProc IS
BEGIN
privateProc; --exec privateProc;
END;
PROCEDURE privateProc IS
BEGIN
DBMS_OUTPUT.PUT_LINE('test');
END;
END testPackage;
//call testPackage.publicProc

Resources