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
IDENTITY_INSERT
is off! If you're not clear whether something stays the same session, google sessions (not exactly = connections), check outsys.dm_exec_sessions
andsys.dm_exec_connections
, or downloadsp_WhoIsActive
andEXEC sp_WhoIsActive @show_sleeping_spids = 2, @show_own_spid = 1
– Turanian