2012-05-17 25 views
51

He buscado esto, pero los hilos en los que parecía tendían a tener respuestas de personas que no entendían la pregunta.¿Cómo se comprueba si IDENTITY_INSERT está configurado en ON u OFF en SQL Server?

Tome la siguiente sintaxis:

SET IDENTITY_INSERT Table1 ON 

¿Cómo se hace algo más a esto:

GET IDENTITY_INSERT Table1 

que no quieren hacer nada en absoluto a los datos en la base de datos o al ajustes para obtener esta información sin embargo. ¡Gracias!

+2

Es curioso cómo mencionaste a las personas que malinterpretaron la pregunta y la gran mayoría de las respuestas aquí haciendo exactamente eso. – Fishcake

+2

Para usted y otros usuarios de Google, la verdadera pregunta: * sesiones *. Probablemente solo quiera comprobar/restaurar el valor de IDENTITY_INSERT para una * sesión * lo suficientemente larga y complicada como para permitir y luego evitar las inserciones de identidad. (¿Un paso de trabajo que se ejecuta continuamente?) PORQUE si inicia una nueva sesión, 'IDENTITY_INSERT' está desactivado. Si no está seguro de si algo se mantiene en la misma sesión, las sesiones de google (no exactamente = conexiones), consulte 'sys.dm_exec_sessions' y' sys.dm_exec_connections', o descargue 'sp_WhoIsActive' y' EXEC sp_WhoIsActive @show_sleeping_spids = 2, @show_own_spid = 1' –

Respuesta

25

Dado que SET IDENTITY_INSERT es una sesión sensible, se gestiona en el nivel de búfer sin almacenar en alguna parte. Esto significa que no necesitamos verificar el estado IDENTITY_INSERT ya que nunca usamos esta palabra clave en la sesión actual.

Disculpe, no hay ayuda para esto.

gran pregunta, sin embargo :)

Fuente: Here

actualización Hay maneras de hacer esto tal vez, también se observan en el sitio he vinculado, OMI, es demasiado esfuerzo para ser útil .

if 

(select max(id) from MyTable) < (select max(id) from inserted) 

--Then you may be inserting a record normally 

BEGIN 
    set @I = 1 --SQL wants something to happen in the "IF" side of an IF/ELSE 
END 

ELSE --You definitely have IDENTITY_INSERT on. Done as ELSE instead of the other way around so that if there is no inserted table, it will run anyway 


BEGIN 
.... Code that shouldn't run with IDENTITY_INSERT on 
END 
+0

Gracias. Me enteré de que existe ayer, así que no estoy seguro de cómo aplicar lo que dices. Básicamente tenemos dos bases de datos en dos servidores diferentes, y apagar cualquiera de ellos y reiniciarlo va a ser un problema. ¿La sesión a la que se refiere dura más de un par de minutos si el servicio de la base de datos se deja funcionando indefinidamente? Básicamente, establezco el valor varias veces en una de las bases de datos sin tomar notas de antemano, y necesito asegurarme de que cualquier cambio como ese se retrotrae. – Panzercrisis

+1

Tenga en cuenta que esto no es una respuesta mía, sino de mi fuente en http://social.msdn.microsoft.com/Forums/en/transactsql/thread/1a6ba2bb-5e82-47e8-a1a0-16fc044b951e (foros oficiales de Microsoft , tienen un montón de esos marcados). Todo depende del rendimiento en estos servidores. Obviamente, si los servidores son lentos/los servicios con respecto a SQL Server se están cerrando, este código (en pseudo aquí) no funcionará bien. ¿Por qué exactamente necesitas saber el estado de identidad de las tablas? Si el servicio se ejecuta indefinidamente, esta sesión no debería durar mucho (según la especificación del servidor y el tamaño de la tabla) ... – Eon

+0

Solo intento restablecer la base de datos a como estaba antes de empezar a jugar con los valores de IDENTITY_INSERT . – Panzercrisis

3

Si quiere saber sobre la variable de la sesión ... Buena pregunta, pero no puedo ver dónde esta información podría ser útil. En la ejecución normal para verificar una respuesta de tabla normal a un inserto, ¡esto debería funcionar!

- Si sólo desea saber si existe la inserción de identidad en una tabla dada:

select is_identity 
from sys.columns 
where object_id = OBJECT_ID('MyTable', 'U') and name = 'column_Name' 

- O ... Utilice esta opción si desea ejecutar algo en función del resultado:

if exists (select * 
from sys.columns 
where object_id = OBJECT_ID('MyTable', 'U') and is_identity = 1) 
... your code considering identity insert 
else 
... code that should not run with identity insert 

¡Diviértete!

+5

Esto no entiende, la pregunta es si 'IDENTITY_INSERT' está activado no si la tabla tiene una columna de identidad – Fishcake

+0

' is_identity' columna en la tabla 'sys.columns' identifica si esa columna es una columna de identidad o no, no si la variable 'IDENTITY_INSERT' es' ON' o 'OFF' –

0

también se puede utilizar el método ObjectProperty para determinar si una tabla tiene una identidad:

DECLARE @MyTableName nvarchar(200) 
SET @MyTableName = 'TestTable' 
SELECT CASE OBJECTPROPERTY(OBJECT_ID(@MyTableName), 'TableHasIdentity') 
WHEN 1 THEN 'has identity' 
ELSE 'no identity columns' 
END as HasIdentity 
1

Muy buena pregunta. Tengo el mismo problema. ¿Puede ser que pueda intentar restablecer IDENTITY_INSERT usando TRY/CATCH? Por ejemplo, realiza el trabajo pero no está seguro de si el trabajo está terminado e IDENTITY_INSERT está establecido en OFF.

¿Por qué no lo intentas:

BEGIN TRY 
... 
END TRY 
BEGIN CATCH 
SET IDENTITY_INSERT table OFF; 
END CATCH; 

Además no estoy seguro de que esto está funcionando correctamente, pero veo que la adición única SET IDENTITY_INSERT ... OFF no arrojó error. Por lo tanto, puede establecerlo solo en caso de que al final SET IDENTITY_INSERT ... OFF.

12

En resumen: solución

  • de Nathan es el más rápido:

    SELECT OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity'); 
    
    • cuando se utiliza un envoltorio de API, se puede reducir todo el cheque a sólo la comprobación de filas. Por ejemplo cuando se utiliza C# 's SqlDataReaders propiedad HasRows y una consulta de la construcción como:

      SELECT CASE OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity') 
           WHEN 1 THEN '1' ELSE NULL END 
      
  • solución de Ricardo permite una mayor flexibilidad, pero requiere nombre de identidad de la columna

    solución
    SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('MyTable', 'U') 
             AND name = 'MyTableIdentityColumnName'; 
    
  • Bogdan Bodanov, utilizando try/catch funcionaría también, pero la comprobación adicional debe limitar el manejo de excepciones a los casos de IDENTITY_INSERT is already ON for table 'MyTable'. Cannot perform SET operation for table 'MyTable';

5

Si está intentando desactivar IDENTITY_INSERT para alguna otra tabla para evitar que se produzca un error cuando quiere establecer IDENTITY_INSERT, también puede funcionar lo siguiente. Como otros han dicho en este hilo, IDENTITY_INSERT es una configuración de sesión sin visibilidad directa. Sin embargo, hice el descubrimiento interesante de que SET IDENTITY_INSERT OFF no tiene errores para ninguna tabla que tenga una identidad, ya sea que IDENTITY_INSERT esté activado o no para esa tabla. Así que se me ocurrió que podía simplemente llamar a SET IDENTITY_INSERT ... OFF para cada tabla con una identidad en la base de datos. Se siente un poco como una solución de fuerza bruta, pero Encontré que el siguiente bloque de SQL dinámico hizo el truco muy bien.

---- make sure IDENTITY_INSERT is OFF ---- 
DECLARE @cmd NVARCHAR(MAX) 
SET @cmd = CAST((SELECT 'SET IDENTITY_INSERT ' + 
      QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' + 
      QUOTENAME(t.name) + ' OFF' + CHAR(10) 
      FROM sys.columns c 
      JOIN sys.tables t ON t.object_id = c.object_id 
      WHERE c.is_identity = 1 
      ORDER BY 1 FOR XML PATH('')) AS NVARCHAR(MAX)) 
EXEC sp_executesql @cmd 
2

Puede descubrir si identity_insert está activado o no y, de ser así, para qué tabla usar el código siguiente.

declare @tableWithIdentity varchar(max) = ''; 
SET IDENTITY_INSERT ExampleTable ON 

begin try 
    create table #identityCheck (id int identity(1,1)) 
    SET IDENTITY_INSERT #identityCheck ON 
    drop table #identityCheck 
end try 
begin catch 
    declare @msg varchar(max) = error_message() 
    set @tableWithIdentity= @msg; 
    set @tableWithIdentity = 
    SUBSTRING(@tableWithIdentity,charindex('''',@tableWithIdentity,1)+1, 10000) 

    set @tableWithIdentity = SUBSTRING(@tableWithIdentity,1, charindex('''',@tableWithIdentity,1)-1) 

    print @msg; 
    drop table #identityCheck 
end catch 

if @tableWithIdentity<>'' 
begin 
    print ('Name of table with Identity_Insert set to ON: ' + @tableWithIdentity) 
end 
else 
begin 
    print 'No table currently has Identity Insert Set to ON' 
end 
+0

buen truco con try-catch – Graeme

+1

@Graeme: gracias, pensé que una respuesta real a la pregunta podría ser útil y esa es la única forma en que sé hacerlo. – jmoreno

Cuestiones relacionadas