Question

Quand j'insérer dans les tables à l'aide au lieu de déclencheurs, @@Identity, IDENT_CURRENT('Table') et SCOPE_IDENTITY() return null. Comment puis-je obtenir la dernière identité de ligne insérée?

Était-ce utile?

La solution

Avec un déclencheur INSTEAD_OF cela signifie pas insérer encore eu lieu. Vous ne pouvez pas connaître l'identité car il n'a pas encore été généré. Faufilant la valeur de métadonnées est possible ( DBCC CHECKIDENT ), mais compter sur elle ne fonctionnera pas correctement sous concurrency et d'ailleurs, il requiert des privilèges élevés.

déclencheurs de INSTEAD_OF sont très rarement nécessaires et une odeur grave de code. Etes-vous sûr besoin? Tu ne peux pas faire le travail avec un déclencheur régulier APRÈS?

Autres conseils

Dans votre lieu de détente, vous pouvez certainement obtenir la valeur insérée ... mais pas jusqu'à ce que vous avez effectué l'insert.

USE tempdb;
GO

CREATE TABLE dbo.SmellThis
(
  id INT IDENTITY(1,1),
  name VARCHAR(32)
);
GO

CREATE TRIGGER dbo.SmellThis_First
ON dbo.SmellThis
INSTEAD OF INSERT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @ids TABLE(id INT);

    IF NOT EXISTS 
    (
      SELECT 1 FROM sys.objects AS o
        INNER JOIN inserted AS i
        ON o.name = i.name
    )
    INSERT dbo.SmellThis(name)  
      OUTPUT inserted.id INTO @ids
      SELECT name 
      FROM inserted;

    SELECT id FROM @ids;
END
GO

INSERT dbo.SmellThis(name) SELECT 'Remus';
GO

Résultats:

id
----
1

nettoyage:

DROP TABLE dbo.SmellThis;

En aparté, vous ne devriez jamais, jamais, jamais en utilisant @@IDENTITY ou IDENT_CURRENT() de toute façon. Et SCOPE_IDENTITY devrait être réservé aux situations où vous savez qu'une seule ligne ne peut jamais être inséré. Une idée fausse commune avec des déclencheurs est qu'ils feu par ligne, comme dans d'autres plates-formes, mais dans SQL Server, ils le feu par opération - donc un multi-lignes insert en utilisant VALUES(),(),() ou INSERT...SELECT - qui SCOPE_IDENTITY voulez-vous installerez à votre variable

Problème principal: Trigger et Entity Framework à la fois les travaux d'envergure diffrent. Le problème est que si vous créez une nouvelle valeur de PK dans déclencheur, il est différent portée. Ainsi cette commande renvoie zéro lignes et EF jetteront exception.

La solution est d'ajouter l'instruction SELECT suivante à la fin de votre Trigger:

SELECT * FROM deleted UNION ALL
SELECT * FROM inserted;

à la place de * vous pouvez mentionner tout le nom de colonne comprenant

SELECT IDENT_CURRENT(‘tablename’) AS <IdentityColumnname>
Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top