トリガーの代わりにを使用してテーブルに挿入すると、_@@Identity
_、IDENT_CURRENT('Table')
およびSCOPE_IDENTITY()
はnullを返します。挿入された行の最後のIDを取得するにはどうすればよいですか?
INSTEAD_OFトリガーの場合、挿入はまだ発生していません。 IDはまだ生成されていないため、識別できません。メタデータからの値のスニークは可能です( DBCC CHECKIDENT
)ですが、これに依存することは、同時実行では正しく機能しません。また、昇格された特権が必要です。
INSTEAD_OFトリガーはほとんど必要なく、深刻なコードの臭いがします。本当に必要ですか?通常のAFTERトリガーで作業できませんか?
トリガーの代わりに、挿入された値を確実に取得できます...しかし、挿入を実行するまでは取得できません。
_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
_
結果:
_id
----
1
_
次にクリーンアップします。
_DROP TABLE dbo.SmellThis;
_
余談ですが、決して_@@IDENTITY
_またはIDENT_CURRENT()
を決して使用しないでください。また、_SCOPE_IDENTITY
_は、挿入できる行が1つだけであることがわかっている場合のために予約する必要があります。トリガーに関する一般的な誤解は、他のプラットフォームと同様に、トリガーが行ごとに発生することですが、SQL Serverでは操作ごとに発生するため、VALUES(),(),()
または_INSERT...SELECT
_を使用した複数行の挿入-_SCOPE_IDENTITY
_変数に設定しますか?