I have a blank table for which I've set up a trigger:
CREATE OR REPLACE TRIGGER authors_bir
BEFORE INSERT ON authors
FOR EACH ROW
begin
if upper(:new.name) = 'TEST' then
raise_application_error(-20001, 'Sorry, that value is not allowed.');
end if;
end;
After executing:
insert into AUTHORS
VALUES (1, 'test', '1-Jan-1989', 'M');
Why am I getting ORA-06512 and ORA-04088 error messages in addition to the expected ORA-20001 error prompt?
ErrorMessage
Error starting at line : 5 in command -
insert into AUTHORS
VALUES (1, 'test', '1-Jan-1989', 'M')
Error report -
ORA-20001: Sorry, that value is not allowed.
ORA-06512: at "RPS.AUTHORS_BIR", line 3
ORA-04088: error during execution of trigger 'RPS.AUTHORS_BIR'
Your trigger works perfectly and ORA-06512 is part of debugging mode and tells you what line of code raised that ORA-20001 that you coded. While ORA-04088 is saying that an error has occurred in the trigger. Both error codes are GENERIC part of oracle troubleshooting report.
According to documentation:
ORA-06512: at stringline string
Cause: Backtrace message as the stack is unwound by unhandled exceptions.
Basically, this error is part of the error stack telling at which line the actual error occurred.
And documentation:
ORA-04088: error during execution of trigger 'string.string'
Cause: A runtime error occurred during execution of a trigger.
And this error is a part of the error stack telling you that error actually occurred in a trigger.
When an unhandled error occurs, error stack is always displayed. If you want to display just the error message, you could use an exception handling part so body of the trigger would look something like this:
begin
if upper(:new.name) = 'TEST' then
raise_application_error(-20001, 'Sorry, that value is not allowed.');
end if;
exception
when others then
dbms_output.put_line(sqlcode|' '|sqlerrm);
end;
Related
I'm trying to do this
INSERT INTO INSPECTIONOFFICE (INSPOFFICE_ID, INSPOFFICE_NAME, INSPOFFICE_STREET, INSPOFFICE_CITY, INSPOFFICE_STATE, INSPOFFICE_ZIPCODE, INSPOFFICE_CONTPERSONFNAME, INSPOFFICE_CONTPERSONLNAME, INSPOFFICE_CONTPERSONPHONE, INSPOFFICE_CONTPERSONEMAIL)
VALUES (12, 'InspectionOffice1', '121 Ames st', 'Omaha', 'NE', 68128, 'Brad', 'Foley', '4022853487', 'BradFoley#gmail.com');
but I get an error
Error starting at line : 22 in command -
INSERT INTO INSPECTIONOFFICE (INSPOFFICE_ID, INSPOFFICE_NAME, INSPOFFICE_STREET, INSPOFFICE_CITY, INSPOFFICE_STATE, INSPOFFICE_ZIPCODE, INSPOFFICE_CONTPERSONFNAME, INSPOFFICE_CONTPERSONLNAME, INSPOFFICE_CONTPERSONPHONE, INSPOFFICE_CONTPERSONEMAIL)
VALUES (12, 'InspectionOffice1', '121 Ames st', 'Omaha', 'NE', 68128, 'Brad', 'Foley', '4022853487', 'BradFoley#gmail.com')
Error at Command Line : 22 Column : 13
Error report -
SQL Error: ORA-04098: trigger 'JMEEK.INSPECTIONOFFICE_INSPECTIONOFF' is invalid and failed re-validation
04098. 00000 - "trigger '%s.%s' is invalid and failed re-validation"
*Cause: A trigger was attempted to be retrieved for execution and was found to be invalid. This also means that compilation/authorization failed for the trigger.
*Action: Options are to resolve the compilation/authorization errors, disable the trigger, or drop the trigger.
Any idea how to fix this?
seems you do not have permission access to the trigger JMEEK.INSPECTIONOFFICE_INSPECTIONOFF
or have some compilation problem with it...
you should take a look in the trigger.
or if you don't know what a trigger is, call a experienced job's teammate. :)
btw, if you are alone, and it don't matter too much.. you can disable / drop the trigger..
this command disable, you can enable later
ALTER TRIGGER JMEEK.INSPECTIONOFFICE_INSPECTIONOFF DISABLE;
this command drop the trigger, you will lose it forever (if you don't have a backup)
drop trigger JMEEK.INSPECTIONOFFICE_INSPECTIONOFF;
The trigger JMEEK.INSPECTIONOFFICE_INSPECTIONOFF, which I am guessing you wrote because it's in the JMEEK schema, which (again I'm guessing) seems to be yours, is invalid, meaning it has compilation errors. To find out what those errors are you should execute the query
SELECT *
FROM ALL_ERRORS
WHERE OWNER = 'JMEEK' AND
NAME = 'INSPECTIONOFFICE_INSPECTIONOFF'
ORDER BY SEQUENCE
None of us can do much else for you because we don't know what this trigger looks like. If you need to see the source code you can execute the following query:
SELECT LINE, TEXT
FROM ALL_SOURCE
WHERE OWNER = 'JMEEK' AND
NAME = 'INSPECTIONOFFICE_INSPECTIONOFF'
ORDER BY LINE
Or you can use an IDE such as Oracle's free SQL Developer product which will make all this a lot easier for you.
In SQL Developer, when running some PL/SQL, when the procedure is completed, the message 'PL/SQL procedure successfully completed.' is returned.
The PL/SQL that is run may return error messages to the user if the operation could not be completed for any reason through DBMS_OUTPUT.PUT_LINE, however, the user will also see 'PL/SQL procedure successfully completed.', which could be misleading (especially if the Script Output window is small enough that the DBMS_OUTPUT is not visible).
Is there any way to have the DBMS_OUTPUT return what it should whilst also having the script not return 'PL/SQL procedure successfully completed.'?
If not, are there any alternatives in SQL Developer that I may be unaware of to provide instant personalised feedback to the user?
declare
testex exception;
begin
if 1=1 then
raise testex;
end if;
exception when testex then
dbms_output.put_line('Error msg');
end;
Below code works in my end. Did you try to run your code like below?
Copied text from a website to explain the SET FEEDBACK OFF command.
Source link: https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12040.htm
SET FEED[BACK] {6 | n | ON | OFF} -
Displays the number of records returned by a script when a script selects at least n records.
ON or OFF turns this display on or off. Turning feedback ON sets n to 1. Setting feedback to zero is equivalent to turning it OFF.
SET FEEDBACK OFF also turns off the statement confirmation messages such as 'Table created' and 'PL/SQL procedure successfully completed' that are displayed after successful SQL or PL/SQL statements.
Add a RAISE statement in the error handler to re-raise the exception so that any outer handler can deal with it:
declare
testex exception;
begin
if 1=1 then
raise testex;
end if;
exception when testex then
dbms_output.put_line('Error msg');
RAISE; -- re-raise the exception to an outer handler
end;
Best of luck.
You have coded it explicitly to complete successfully in the event of a testex exception. The code says: if this happens, then print a message and end. If you want it to actually fail then it needs to raise an exception.
I would just use something like this:
begin
if 1=1 then
raise_application_error(-20000, 'Bananas are not available on a Tuesday');
end if;
end;
/
begin
*
ERROR at line 1:
ORA-20000: Bananas are not available on a Tuesday
ORA-06512: at line 3
This will cause an actual error, rather than just printing out a message that happens to talk about an error, allowing you to control deployments and build scripts etc.
It will also roll back any uncommitted transactions within the block, which your current approach does not, and it will show the actual line number.
When I execute the batch of insert queries via SQL Server Mgmt Studio, it produces the following error but completes the insertion process of other queries.
Msg 18054, Level 16, State 1, Procedure X, Line 14
Error 50001, severity -1, state 1 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.
Msg 18054, Level 16, State 1, Procedure Y, Line 14
Error 50001, severity -1, state 1 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.
Msg 18054, Level 16, State 1, Procedure Z, Line 14
Error 50001, severity -1, state 1 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.
But, while executing via ant job in terminal the insertion queries, the process halts with the below error message.
BUILD FAILED
C:\test\mssql\build.xml:27: The following error occurred while executing this line:
C:\test\mssql\build-core.xml:74: com.microsoft.sqlserver.jdbc.SQLServerException: Error 50001,
severity -1, state 1 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000,
make sure the user-defined message is added using sp_addmessage.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
I tried to handle the error by ignoring it:
set ANSI_WARNINGS OFF;
And by defining the try-catch block for the procedures throwing the error:
BEGIN TRY
RAISERROR (50001,-1,1, 'X');
RAISERROR (50001,-1,1, 'Y');
RAISERROR (50001,-1,1, 'Z');
END TRY
BEGIN CATCH
DECLARE #ErrorMessage NVARCHAR(4000);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SELECT
#ErrorMessage = ERROR_MESSAGE(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
RAISERROR (#ErrorMessage, -- Message text.
#ErrorSeverity, -- Severity.
#ErrorState -- State.
);
END CATCH;
But the error still persists in terminal with build failure.
If I define the custom error message as below:
EXEC sp_addmessage 50001, 16, N'Test Message';
GO
I just received the above error message in place of but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.
What could be the way such that the procedure throwing error gets handled and insertion continues further till the end like that of SQL client.
Thinking some more about what you must be trying to ask, I think the answer to your question is this:
You need to put EACH statement that might cause an error that you would want to ignore in its own TRY..CATCH block. In each catch block, you can decide based on the error message whether you want to THROW it and stop processing, or do nothing but maybe store it in a variable, and continue.
Then at the end of everything you can check your variable(s) to see if there were any errors that you ignored and THROW them at that time (if you even want to), without rolling back the statements that have already run successfully.
I have some procedure written in Oracle. Unfortunately I can't show its code. Somewhere inside it is select where execution crashed because of absence of required data. It looks like this
select value into l_value
from config
where code = upper(p_code);
So when I call this procedure like this (in SqlDeveloper)
execute some_package.some_procedure('CODE');
it throws
Error report -
ORA-01403: no data found
ORA-06512: at "XXXXXXXXXXXXXXXXXXX", line 111
ORA-06512: at "XXXXXXXXXXXXXXXXXXX", line 111
ORA-06512: at line 1
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
But when I call it like this
call some_package.some_procedure('CODE');
it crashes at the same place (as I can suggest from the result, stored in DB), but it does no throw an exception.
some_package.some_procedure('CODE') succeeded.
What happens? And why there is such difference?
NO_DATA_FOUND exception behavior is special. It is handled by default in SQL context but not in PL/SQL. In SQL no data found is not considered as an error, it happens all the time that there is no data that meets certain condition.
CALL is SQL command whereas EXEC is a shortcut for BEGIN <code> END; which is PL/SQL.
I rise DUP_VAL_ON_INDEX in SQL and I'd like to associate some custom error message with it.
Right now after executing the code
IF ___SOME_CONDITION___ THEN
RAISE DUP_VAL_ON_INDEX;
END IF
I see following message:
00001. 00000 - "unique constraint (%s.%s) violated"
How I can provide custom message to substitute these "%s"?
You wouldn't typically raise these pre-defined errors yourself. Instead, you would either let the database raise them (eg. you really have tried to insert a row that violates the unique constraint/index) or raise your own custom error (eg. raise_application_error()) and provide the necessary information there.