views:

1087

answers:

3

(SQL 2005) Is it possible for a raiserror to terminate a stored proc.

For example, in a large system we've got a value that wasn't expected being entered into a specific column. In an update trigger if you write:

if exists (select * from inserted where testcol = 7) begin raiseerror('My Custom Error', 16, 1) end

the update information is still applied. however if you run

if exists (select * from inserted where testcol = 7) begin select 1/0 end

a divide by 0 error is thrown that actually terminates the update. is there any way i can do this with a raiseerror so i can get custom error messages back?

A: 

You should check for valid data prior to performing the update.

IF (@testvalue = 7)
    RAISERROR("Invalid value.", 16, 1);
ELSE
    UPDATE...
NYSystemsAnalyst
what if the data changes between the check and the update?
KM
The data in this example is an input parameter and this shouldn't change unless the sproc explicitly changes it.
pjp
I don't know which sproc is updating this or if its a nightly database job, so i can't check the value before updating it.
Bob
Do you want this mystery job to blow up when it tries to enter this value?
pjp
+1  A: 

Can you not just add a CHECK constraint to the column to prevent it from being inserted in the first place?

ALTER TABLE YourTable ADD CONSTRAINT CK_No_Nasties
    CHECK (testcol <> 7)

Alternatively you could start a transaction in your insert sproc (if you have one) and roll it back if an error occurs. This can be implemented with TRY, CATCH in SQL Server 2005 and avoids having to use a trigger.

pjp
+4  A: 

In a trigger, issue a ROLLBACK, RAISERROR and then RETURN.

see Error Handling in SQL Server - Trigger Context by Erland Sommarskog

KM
Also this link http://support.microsoft.com/kb/45581
pjp
Is this only valid for a transaction? or are triggers trasactional?
Bob
From the link I posted 'When within a trigger, it is not necessary to have a matching BEGIN TRANSACTION statement because each SQL statement that is not within an explicit transaction is effectively a one-statement transaction.'
pjp
from my link: _A trigger always executes in the context of a transaction, since even if there is no multi-statement transaction in progress each INSERT, UPDATE and DELETE statement is its own transaction in SQL Server, and the trigger is part of that transaction._
KM
YEAH! your the don! Our dba hass issues with trasactions so we don't tend to research down that path, i wasn't aware that triggers fell within transactional procedures (although now you've made me think about it thats pretty obvious).Thanks!
Bob