HiveBrain v1.2.0
Get Started
← Back to all entries
debugsqlModerate

How can I handle unwanted, non-erroneous situations better?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
canhandlenonerroneousbetterhowunwantedsituations

Problem

When writing procedures, I occasionally encounter situations in which I want to abort the procedure, even if the situation didn't necessarily trigger an error.

Let's say, if I don't want John to be able to run this procedure, I'd do something like this:

IF @UserName = 'John'
BEGIN
    RAISERROR('John, get out', 16, 1);
    RETURN 1;
END


I don't really have a good reason for returning 1, it's mostly a remnant from shell scripting, and I'm open for better ways to do this.

Is there a better way of returning an error message and returning control to the caller for unwanted situations that aren't strictly speaking errors? I am not interested in reducing the amount of characters or lines of code. I just had a gut feeling saying "this is probably not the best way to solve this problem", and I was curious if there were smarter ways to do this.

One alternative could be by always using TRY/CATCH, since RAISERROR with a severity of 1-19 will hand control to the catch clause.

Example:

BEGIN TRY
    PRINT 'Before RAISERROR';
    RAISERROR('Time for errors', 16, 1);
    PRINT 'After RAISERROR'
END TRY
BEGIN CATCH
    DECLARE @Msg NVARCHAR(255) = ERROR_MESSAGE()
    PRINT 'Inside CATCH'
    RAISERROR(@Msg, 16, 1)
END CATCH


Output:

Before RAISERROR
Inside CATCH
Msg 50000, Level 16, State 1, Line 13
Time for errors


Con: Requires the presence of TRY/CATCH blocks.

Solution

Is there a more terse way of returning an error message and returning
control to the caller for unwanted situations that aren't strictly
speaking errors?

You can use THROW


Raises an exception and transfers execution to a CATCH block of a
TRY…CATCH construct ... If a TRY…CATCH construct is not available, the
session is ended.

IF @UserName = 'John'
    THROW 50000, 'John, get out', 1;


The above is somewhat more terse as it is just a single statement and doesn't need the RETURN so you can also drop the BEGIN and END

Code Snippets

IF @UserName = 'John'
    THROW 50000, 'John, get out', 1;

Context

StackExchange Database Administrators Q#141281, answer score: 11

Revisions (0)

No revisions yet.