web-dev-qa-db-fra.com

Comment vérifier si IDENTITY_INSERT est défini sur ON ou OFF dans SQL Server?

J'ai cherché cela, mais les sujets dans lesquels il apparaissait avaient tendance à avoir des réponses de personnes qui ne comprenaient pas la question. 

Prenez la syntaxe suivante:

SET IDENTITY_INSERT Table1 ON

Comment faites-vous quelque chose de plus comme ça:

GET IDENTITY_INSERT Table1

Je ne veux cependant rien faire des données dans la base de données ou des paramètres pour obtenir cette information. Merci!

60
Panzercrisis

Étant donné que SET IDENTITY_INSERT est sensible à la session, il est géré au niveau de la mémoire tampon sans stockage quelque part. Cela signifie que nous n'avons pas besoin de vérifier le statut IDENTITY_INSERT car nous n'utilisons jamais cette clé Word dans la session en cours.

Désolé, aucune aide pour cela.

Bonne question cependant :)

Source: ici

Mise à jour Il existe peut-être des moyens de le faire, également vu sur le site que j'ai lié, OMI, c'est trop d'efforts pour être utile.

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
27
Eon

En résumé:

  • La solution de Nathan est la plus rapide:

    SELECT OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity');
    
    • lors de l'utilisation d'un wrapper d'API, on peut réduire la vérification complète à une simple vérification des lignes. Par exemple, lorsque vous utilisez la propriété SqlDataReaders de C #, HasRows, et une structure de requête telle que:

      SELECT CASE OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity')
             WHEN 1 THEN '1' ELSE NULL END
      
  • La solution de Ricardo permet plus de flexibilité mais nécessite le nom d'identité de la colonne

    SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('MyTable', 'U') 
                            AND name = 'MyTableIdentityColumnName';
    
  • La solution Bogdan Bodanov, utilisant try/catch, fonctionnerait également, mais une vérification supplémentaire devrait limiter le traitement des exceptions aux cas de IDENTITY_INSERT is already ON for table 'MyTable'. Cannot perform SET operation for table 'MyTable'; 

16
Lorenz Lo Sauer

Si vous essayez de désactiver IDENTITY_INSERT pour une autre table afin d'éviter de générer une erreur lorsque vous souhaitez définir IDENTITY_INSERT sur, les opérations suivantes peuvent également fonctionner pour vous. Comme d'autres l'ont déjà dit sur ce fil, IDENTITY_INSERT est un paramètre de session sans visibilité directe. Cependant, j'ai découvert la découverte intéressante que SET IDENTITY_INSERT OFF n'erreur pas pour les tables ayant une identité, que IDENTITY_INSERT soit activé ou non pour cette table. Je me suis donc dit que je pouvais appeler SET IDENTITY_INSERT ... OFF pour chaque table ayant une identité dans la base de données. Cela ressemble un peu à une solution de force brute, mais J'ai trouvé que le bloc SQL dynamique suivant faisait très bien l'affaire. 

---- 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
6
Mike Stankavich

Vous pouvez découvrir si identity_insert est activé ou non et, le cas échéant, pour quelle table à l'aide du code ci-dessous.

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 
4
jmoreno

Si vous voulez en savoir plus sur la variable de session ... Bonne question, mais je ne vois pas où cette information serait utile. En exécution normale pour vérifier une réponse de table normale à une insertion, cela devrait fonctionner!

- Si vous voulez seulement savoir s’il existe une insertion d’identité sur une table donnée:

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

- Ou ... Utilisez ceci si vous voulez exécuter quelque chose en fonction du résultat:

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

S'amuser!

3
Ricardo

Très bonne question. J'ai le même problème. Peut-être que vous pouvez essayer de réinitialiser IDENTITY_INSERT en utilisant TRY/CATCH? Par exemple, vous effectuez le travail sans savoir si le travail est terminé et si IDENTITY_INSERT est défini sur OFF.

Pourquoi n'essayez-vous pas:

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

De plus, je ne suis pas sûr que cela fonctionne correctement, mais je constate que l'ajout de SET IDENTITY_INSERT ... OFF n'a pas renvoyé d'erreur. Donc, vous pouvez définir juste au cas où à la fin SET IDENTITY_INSERT ... OFF.

1
Bogdan Bogdanov

vous pouvez également utiliser la méthode ObjectProperty pour déterminer si une table a une identité:

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
0
Nathan Tregillus