How do you check if IDENTITY_INSERT is set to ON or OFF in SQL Server?

前端 未结 8 968
暗喜
暗喜 2020-12-09 00:52

I\'ve searched for this, but threads in which it appeared tended to have answers from people who didn\'t understand the question.

Take the following syntax:

<
8条回答
  •  南方客
    南方客 (楼主)
    2020-12-09 01:08

    Here is my solution. It is very similar to @jmoreno's answer.

    You would call it like this

    DECLARE @IdentityInsert VARCHAR(20)
    EXEC dbo.GetIdentityInsert 'YourDb', 'YourSchema', 'YourTable', @IdentityInsert OUT
    SELECT @IdentityInsert 
    

    This returns a 1-row recordset with column name IDENTITY_INSERT, that can be either ON, OFF, or NO_IDENTITY (if the given table doesn't have an identity column). It also sets the output parameter @IdentityInsert. So you can adjust the code to whichever method you prefer.

    It would be nice to get this into a user-defined function, but unfortunately I couldn't find a way to avoid the TRY..CATCH block, which you cannot use in user-defined functions.

    -- ================================================================================
    -- Check whether the table specified has its IDENTITY_INSERT set to ON or OFF.
    -- If the table does not have an identity column, NO_IDENTITY is returned.
    -- Tested on SQL 2008.
    -- ================================================================================
    CREATE PROCEDURE dbo.GetIdentityInsert
    
          @dbname sysname
        , @schemaname sysname
        , @table sysname
        , @IdentityInsert VARCHAR(20) OUTPUT
    
    AS
    
    BEGIN
    
        SET NOCOUNT ON
    
        DECLARE @OtherTable nvarchar(max)
        DECLARE @DbSchemaTable nvarchar(max)
    
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
        DECLARE @ErrorNumber INT;
        DECLARE @object_id INT;
    
        SET @DbSchemaTable = @dbname + '.' + @schemaname + '.' + @table
    
        SET @object_id = OBJECT_ID(@DbSchemaTable)
        IF @object_id IS NULL
        BEGIN
            RAISERROR('table %s doesn''t exist', 16, 1, @DbSchemaTable)
            RETURN
        END
    
    
        BEGIN TRY
    
            SET @object_id = OBJECT_ID(@DbSchemaTable)
    
            IF OBJECTPROPERTY(@object_id,'TableHasIdentity') = 0
            BEGIN
                SET @IdentityInsert = 'NO_IDENTITY'
            END
            ELSE
            BEGIN
                -- Attempt to set IDENTITY_INSERT on a temp table. This will fail if any other table
                -- has IDENTITY_INSERT set to ON, and we'll process that in the CATCH
                CREATE TABLE #GetIdentityInsert(ID INT IDENTITY)
                SET IDENTITY_INSERT #GetIdentityInsert ON
                SET IDENTITY_INSERT #GetIdentityInsert OFF
                DROP TABLE #GetIdentityInsert
    
                -- It didn't fail, so IDENTITY_INSERT on @table must set to OFF
                SET @IdentityInsert = 'OFF'
            END
        END TRY
    
    
        BEGIN CATCH
    
            SELECT 
                @ErrorMessage = ERROR_MESSAGE(),
                @ErrorSeverity = ERROR_SEVERITY(),
                @ErrorState = ERROR_STATE(),
                @ErrorNumber = ERROR_NUMBER();
    
            IF @ErrorNumber = 8107  --IDENTITY_INSERT is already set on a table
            BEGIN
                SET @OtherTable = SUBSTRING(@ErrorMessage, CHARINDEX(char(39), @ErrorMessage)+1, 2000)
                SET @OtherTable = SUBSTRING(@OtherTable, 1, CHARINDEX(char(39), @OtherTable)-1)
    
                IF @OtherTable = @DbSchemaTable 
                BEGIN
                    -- If the table name is the same, then IDENTITY_INSERT on @table must be ON
                    SET @IdentityInsert = 'ON'
                END
                ELSE
                BEGIN
                    -- If the table name is different, then IDENTITY_INSERT on @table must be OFF
                    SET @IdentityInsert =  'OFF'
                END
            END
            ELSE
            BEGIN
                RAISERROR (@ErrorNumber, @ErrorMessage, @ErrorSeverity, @ErrorState);
                --THROW     Use this if SQL 2012 or higher
            END
    
        END CATCH
    
        SELECT [IDENTITY_INSERT] = @IdentityInsert
    END
    GO
    

提交回复
热议问题