SQL Server TRY CATCH FINALLY

前端 未结 6 2042
执笔经年
执笔经年 2021-02-06 23:09

I have a scenario where I need something similar to .NET\'s try-catch-finally block.

On my try, I will CREATE a #temp table, INSERT

相关标签:
6条回答
  • 2021-02-06 23:29

    using custom error number to indicate there no real error, just final code?

    -- create temp table;
    BEGIN TRY
        -- use temp table;
        THROW 50555;
    END TRY
    BEGIN CATCH
        -- drop temp table;
        IF ERROR_NUMBER() <> 50555
            THROW;  -- rethrow the error
    END CATCH
    
    0 讨论(0)
  • 2021-02-06 23:32

    Local temp tables (e.g., "#Temp") are automatically dropped when the SQL connection ends. It's good practice to include an explicit DROP command anyway, but if it doesn't execute, the table will still be dropped.

    If you must ensure that a DROP executes as soon as possible, you'll have to repeat the DROP command in a CATCH clause, since there's no FINALLY:

    -- create temp table;
    BEGIN TRY
        -- use temp table;
        -- drop temp table;
    END TRY
    BEGIN CATCH
        -- drop temp table;
        THROW;  -- rethrow the error
    END CATCH
    

    Table variables are an alternative: they're dropped when the variable goes out of scope. However, table variables do not support statistics, so if the table variable is large and used in multiple queries, it may not perform as well as a temp table.

    0 讨论(0)
  • 2021-02-06 23:34

    While not exactly the same as FINALLY, the T-SQL version of Try-Catch does allow that code that needs execute after both the Try and Catch blocks can occur after the end of the END CATCH statement. Using the question code as an example:

        BEGIN TRY
          CREATE TABLE #temp
           (
             --columns
           )
          --Process data with other data sets
        END TRY
        BEGIN CATCH
        EXECUTE usp_getErrorMessage
        END CATCH;
    
    IF OBJECT_ID('tempdb..#temp') IS NOT NULL -- Check for table existence
        DROP TABLE #temp;
    

    The DROP TABLE command will execute whether the Try or Catch execute. See: BOL Try...Catch

    0 讨论(0)
  • 2021-02-06 23:35

    "FINALLY" is often, but not always, functionally identical to having the "final" code follow the TRY/CATCH (without a formal "FINALLY" block). Where it is different is the case where something in the TRY/CATCH blocks could cause execution to end, such as a return statement.

    For example, a pattern I've used is to open a cursor, then have the cursor-using code in the TRY block, with the cursor close/deallocate following the TRY/CATCH block. This works fine if the blocks won't exit the code being executed. However, if the TRY CATCH block does, for example, a RETURN (which sounds like a bad idea), if there were a FINALLY block, it would get executed, but with the "final" code placed after the TRY / CATCH, as T-SQL requires, should those code blocks cause the execution to end, that final code won't be called, potentially leaving an inconsistent state.

    So, while very often you can just put the code after the TRY/CATCH, it will be a problem if anything in those blocks could terminate without falling through to the cleanup code.

    0 讨论(0)
  • 2021-02-06 23:47

    Instead of creating a table you could just declare a table variable (which will automatically go away when the query ends).

    BEGIN TRY
    DECLARE @temp TABLE
    (
        --columns
    )
    --do stuff
    END TRY
    BEGIN CATCH
    --do other stuff
    END CATCH
    
    0 讨论(0)
  • 2021-02-06 23:53

    there is no FINALLY equivalent.
    an alternative may be table variables but is not exactly the same and must be evaluated on a case by case basis.
    there is a SO question with details very useful to make an informed choice.
    with table variables you don't need to clean up like you do with temp tables

    0 讨论(0)
提交回复
热议问题