Why does Microsoft recommend THROW over RAISERROR?

  • THROW has more cons than pros. This is the consensus I've encountered among developers.
    This post goes in depth regarding the pitfalls - http://www.sommarskog.se/error_handling/Part2.html#THROW

    Why then does MS recommend using THROW on the RAISERROR page - https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?

    I thought perhaps they're deprecating RAISERROR for their own reasons, but it doesn't look like the case - https://docs.microsoft.com/en-us/sql/database-engine/deprecated-database-engine-features-in-sql-server-2016

  • You can't use RAISERROR in Natively Compiled Stored procs which is probably why MS are saying use throw over raiserror. Plus it is a lot simpler to use than RAISERROR (as shown in the very simplistic example below). I have never come across a con in using throw.

    BEGIN TRY
      SELECT 1 / 0;
    END TRY
    BEGIN CATCH
      THROW;
    END CATCH;

    BEGIN TRY
      SELECT 1 / 0;
    END TRY
    BEGIN CATCH
      DECLARE @ERROR_MESSAGE AS NVARCHAR(4000)
        , @ERROR_SEVERITY AS SMALLINT
        , @ERROR_STATE AS  SMALLINT;
      SELECT @ERROR_MESSAGE = ERROR_MESSAGE()
       , @ERROR_SEVERITY = ERROR_SEVERITY()
       , @ERROR_STATE = ERROR_STATE();
      RAISERROR(@ERROR_MESSAGE, @ERROR_SEVERITY, @ERROR_STATE);
    END CATCH;
    .

  • A general observation is that the overal quality and consistency of Microsoft online documentation is declining. I digress.

    Raiserror has been on the chopping block for some time and Microsoft has been recommending THROW for years. I use THROW a lot and have no problems.

    "I cant stress enough the importance of switching from a sequential files mindset to set-based thinking. After you make the switch, you can spend your time tuning and optimizing your queries instead of maintaining lengthy, poor-performing code."

    -- Itzik Ben-Gan 2001

  • I guess the real question was why did MS not just extend RAISERROR?

    The problems with THROW seem to be:

    • No options such as WITH NOWAIT or WITH LOG (i.e. not as versatile as raiserror). Personally not used very often.
    • Throw is a not a reserved word, so you can get accidental aliasing
    So I was wondering why introduce, and promote the use of, a new command to invoke errors when you could have provided a parameter-less RAISERROR, cause RAISERROR to abort the batch or specify an error number? Figured there must be other differences.

    I thought that perhaps a caller would interpret the exceptions differently, but testing from a simple c# app, RAISERROR and THROW both resolve to SqlException.

  • knightwisp - Monday, May 8, 2017 9:16 AM

    I guess the real question was why did MS not just extend RAISERROR?

    • No options such as WITH NOWAIT or WITH LOG (i.e. not as versatile as raiserror). Personally not used very often.
    • Throw is a not a reserved word, so you can get accidental aliasing
    So I was wondering why introduce, and promote the use of, a new command to invoke errors when you could have provided a parameter-less RAISERROR, cause RAISERROR to abort the batch or specify an error number? Figured there must be other differences.

    I thought that perhaps a caller would interpret the exceptions differently, but testing from a simple c# app, RAISERROR and THROW both resolve to SqlException.

    Without the people who made the decision we can only speculate.
    RAISERROR has been around since SQL Server 7 and probably earlier in Sybase. Maybe it was too complex to enable it to work with Natively Compiled Stored Procs so they came up with Throw. Maybe they wanted it to be similar to throwing an error in c#/c++
    With the growth of in-memory tables etc.it makes sense they want to push people down the road of using throw rather than raiserror

Viewing 5 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic. Login to reply