I'm having an issue on settin up SqlException.Number
On my Stored Proc i'm raising an error
--#number = 50001
RAISERROR(#number, 16, 1) -
I should expect that the Error_Number() should be #number but I always get 18054
Is there something wrong with my RAISERROR?
Check the sys.messages table for error code 74601. if this is a user defined error, it shouold be added in the table.
for any error that is greater than 50000 should give you this output if not found.
Msg 18054, Level 16, State 1, Line 1
Error XXXXX, severity 16, 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.
There is one small caveat: You can't supply a message on your own in this case. But this can be circumvented by adding an additional %s in the sp_addmessage call or by changing all mapped messages to your own pattern and supplying the right parameters in the raiseerror call.
Check there for more information:
SQL Server: Rethrow exception with the original exception number
RAISERROR can either reference a user-defined message stored in the
sys.messages catalog view or build a message dynamically.
Check for your error message exists or not using this:
select * from sys.messages
If it does not exists then Use sp_addmessage to add user-defined error messages and sp_dropmessage to delete user-defined error messages.
for more information follow RaiseError documentation.
Related
I've created a stored procedure that is run as a user defined action for a business rule in MDS. I want to be able to surface up the exceptions I have put in the procedure to be visible to the user executing the business rule as a result of their modification.
It seems like in MDS' built in procedures, e.g. [mdm].[udpValidateEntity] they have used:
RAISERROR (N'MDSERR200226|The entity version cannot be validated. It is the target of a sync relationship.', 16, 1);
This, if copied and pasted in my code results in an expected error popup msg
200226:The entity version cannot be validated. It is the target of a sync relationship.
But when I try to implement this using my own error code and message
IF #err_msg IS NOT NULL
BEGIN;
SET #err_msg = N'MDSERR99999|MDS PROC usr.UpdateInvalidValidityRange' + #err_msg;
RAISERROR (#err_msg, 16, 1);
END;
The error message gets replaced by a generic error message:
99999: A database error has occurred. Contact your system administrator.
Is there a way to surface error messages to the UI?
I've got an insert/update trigger set up which prevents an employee from existing in two tables at the same time. It works fine with catching illegal insertions/updates but i'm also getting another error report when testing the trigger with illegal insertions/updates.
Here's my code:
CREATE OR REPLACE TRIGGER check_foobar
BEFORE INSERT OR UPDATE OF VarX ON FOOBAR
FOR EACH ROW
DECLARE
counter NUMBER(38);
BEGIN
SELECT count(*)
INTO counter
FROM BARFOO
WHERE VarX = :NEW.VarX
GROUP BY VarX;
IF counter > 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'This is an illegal insertion/update');
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('TEST');
END;
/
And the errors ORA-06512 and ORA-04088 i'm not sure of:
SQL> INSERT INTO DRIVER VALUES(2, 10345, 'AVAILABLE');
Error starting at line : 26 File #test.sql
In command -
INSERT INTO FOOBAR VALUES(2)
Error report -
ORA-20001: This is an illegal insertion/update
ORA-06512: at "HR.CHECK_FOOBAR", line 11
ORA-04088: error during execution of trigger 'HR.CHECK_FOOBAR'
When i add an exception handler for the select statement my trigger stops working properly and the illegal insertion isn't prevented. But the execution error is prevented.
UPDATE: I've added a group by and an exception to the trigger, so now the trigger still works with an exception handler but the errors ORA-06512 and ORA-04088 are still coming up with the illegal insertion/update.
Line 11 mentioned in the error is
GROUP BY VarX;
Any advice would be much appreciated.
There is no problem here, it is working as expected.
Error starting at line : 26 File #test.sql
In command -
INSERT INTO FOOBAR VALUES(2)
This is referring to the line in your script where you have the INSERT statement. It's telling you an exception was raised at this point.
Error report -
This is showing the error stack:
ORA-20001: This is an illegal insertion/update
This is the actual exception that was raised.
ORA-06512: at "HR.CHECK_FOOBAR", line 11
ORA-04088: error during execution of trigger 'HR.CHECK_FOOBAR'
These are additional messages just to tell you where the exception was originally raised, in this case, in your trigger on line 11, where the RAISE_APPLICATION_ERROR is, as you might expect. Note that line numbers for triggers refer to the executable portion of the trigger, so in your case the DECLARE is line 1.
The ORA-04088 error means that the trigger has an un-handled exception. You are raising a application error but then not handling it. You need to handle this exception as per below.
CREATE OR REPLACE TRIGGER check_foobar
BEFORE INSERT OR UPDATE OF VarX ON FOOBAR
FOR EACH ROW
DECLARE
counter NUMBER(38);
BEGIN
SELECT count(*)
INTO counter
FROM BARFOO
WHERE VarX = :NEW.VarX
GROUP BY VarX;
IF counter > 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'This is an illegal insertion/update');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('TEST');
WHEN OTHERS THEN
IF SQLCODE = -20001 THEN
-- do some logging
RAISE;
ELSE
-- do some logging and any other actions you feel are needed. Then depending on needs you can raise or not.
END IF;
END;
/
I notice when this error is triggered within the stored procedure it returns 50,000. Is there a way to modify this to say 50,999 so the front-end app can specifically pick the error up and not confuse it with anything else.
RAISERROR('Client already has an Active Visit!',16,1)
As per the documentation of RAISERROR (Transact-SQL):
The message is returned as a server error message to the calling
application or to an associated CATCH block of a TRY…CATCH construct.
New applications should use THROW instead.
Emphasis mine. (THROW (Transact-SQL))
I don't know what your SQL statement looks like, but, instead you can therefore do something like:
BEGIN TRY
--Your INSERT statement
SELECT 0/0; --Causes an error
END TRY
BEGIN CATCH
THROW 50099, 'Client already has an Active Visit!',1;
END CATCH
With RAISEERROR, if you use message as the first parameter then you can't specify an error ID and it is implicitly 50000. However, you can create a custom message with parameters and pass your code there. ie:
RAISERROR('Client already has an Active Visit! - Specific Err.Number:[%d]',16,1, 50999)
Also Try\Catch is the suggested method for new applications.
You need to specify the first parameter of the raiseerror function, like so:
--configure the error message
sp_addmessage #msgnum = 50999,
#severity = 16,
#msgtext = N'Client %s already has an Active Visit!';
GO
-- throw error
RAISERROR (50999, -- Message id.
16, -- Severity,
1, -- State,
N'123456789'); -- First argument supplies the string.
GO
Output will be
Msg 50999, Level 16, State 1, Line 8
Client 123456789 already has an Active Visit!
If you don't specify the error number, the raiserror will be assumed to be 50000. Documentation here...
My application runs SQL scripts to load in data and when there's a problem with the file it's loading, it only logs the last error which doesn't contain the useful information about why the file won't load.
Example code:
BEGIN TRY
BULK INSERT MyTableName
FROM 'C:\MyFilename.txt'
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '\n',
TABLOCK,
MAXERRORS=0,
ERRORFILE = 'C:\MyFilename_Errors.log'
)
;
END TRY
BEGIN CATCH
INSERT INTO MyErrorLog
SELECT ERROR_MESSAGE() as Issue
, ERROR_LINE() as IssueRowNum
;
END CATCH
This script will create an entry in [MyErrorLog] for the third error (see below). And the log file will tell me what line, but not what field:
Row 30539 File Offset 1910820 ErrorFile Offset 0 - HRESULT 0x80004005
Here's all 3 lines if I "THROW" the error inside the CATCH:
Msg 4864, Level 16, State 1, Line 3 Bulk load data conversion error
(type mismatch or invalid character for the specified codepage) for
row 1, column 5 (MyField).
Msg 7399, Level 16, State 1, Line 3 The OLE DB provider "BULK" for
linked server "(null)" reported an error. The provider did not give
any information about the error.
Msg 7330, Level 16, State 2, Line 3 Cannot fetch a row from OLE DB
provider "BULK" for linked server "(null)".
How do I capture that first (and second) error message?
You can only capture a single error in a T-SQL CATCH block. According to this connect item, the workaround is to use THROW (or not use TRY/CATCH) and capture the errors in client code.
Consequently, you'll need to invoke the script from a client application (including SQLCLR) so that you can capture and log all errors.
I am getting a fatal error on following code.
exec [sp_ExternalApp_UPDATEUSER] 'ZZZ', XXXXX','DDDDD','DDDFFDD','EREE', 'EREWWWWW',1,1,'QWEW#DFEE.DER','DEFF','XXXX','DDDD'
Following error occurred:
Location: memilb.cpp:1624
Expression: pilb->m_cRef == 0
SPID: 79
Process ID: 2256
Msg 3624, Level 20, State 1, Procedure sp_ExternalApp_UPDATEUSER, Line 32
A system assertion check has failed. Check the SQL Server error log for details
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.
Thank you
I got the solution.
I have used UPPER() function. As I removed that function, my problem solved
Like the message said, check your error log, there might be more detail in there..what does this proc do does it use sp_OACreate or calls xp_cmdshell? Post the proc code
You might want to check the database for corruption. Try
DBCC CHECKDB
(before doing so, read the documentation on that command! See http://msdn.microsoft.com/en-us/library/ms176064.aspx )