Ketika saya memasukkan ke dalam tabel menggunakan bukan pemicu @@Identity
,, IDENT_CURRENT('Table')
dan SCOPE_IDENTITY()
mengembalikan nol. Bagaimana saya bisa mendapatkan identitas terakhir dari baris yang dimasukkan?
Ketika saya memasukkan ke dalam tabel menggunakan bukan pemicu @@Identity
,, IDENT_CURRENT('Table')
dan SCOPE_IDENTITY()
mengembalikan nol. Bagaimana saya bisa mendapatkan identitas terakhir dari baris yang dimasukkan?
Jawaban:
Dengan pemicu INSTEAD_OF itu berarti belum ada sisipan yang terjadi. Anda tidak dapat mengetahui identitasnya karena belum dibuat. Mengintipkan nilai dari metadata dimungkinkan ( DBCC CHECKIDENT
) tetapi mengandalkannya tidak akan berfungsi dengan benar di bawah konkurensi dan di samping itu membutuhkan hak yang lebih tinggi.
INSTEAD_OF pemicu sangat jarang diperlukan dan bau kode yang serius. Anda yakin membutuhkannya? Tidak bisakah Anda melakukan pekerjaan dengan pemicu SETELAH reguler?
Di alih-alih pemicu, Anda pasti bisa mendapatkan nilai yang dimasukkan ... tetapi tidak sampai setelah Anda melakukan memasukkan.
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
Hasil:
id
----
1
Sekarang bersihkan:
DROP TABLE dbo.SmellThis;
Sebagai tambahan, Anda seharusnya tidak pernah, pernah menggunakan @@IDENTITY
atau IDENT_CURRENT()
tetap. Dan SCOPE_IDENTITY
harus disediakan untuk situasi di mana Anda tahu hanya satu baris yang bisa dimasukkan. Kesalahpahaman umum dengan pemicu adalah bahwa mereka menjalankan per baris, seperti pada platform lain, tetapi dalam SQL Server mereka menjalankan per operasi - jadi masukkan multi-baris menggunakan VALUES(),(),()
atau INSERT...SELECT
- yang SCOPE_IDENTITY
akan Anda atur ke variabel Anda?
Masalah Utama: Kerangka kerja Pemicu dan Entitas bekerja dalam lingkup yang berbeda. Masalahnya adalah, bahwa jika Anda menghasilkan nilai PK baru di pemicu, itu adalah ruang lingkup yang berbeda. Dengan demikian perintah ini mengembalikan nol baris dan EF akan melempar pengecualian.
Solusinya adalah dengan menambahkan pernyataan SELECT berikut di akhir Pemicu Anda:
SELECT * FROM deleted UNION ALL
SELECT * FROM inserted;
di tempat * Anda dapat menyebutkan semua nama kolom termasuk
SELECT IDENT_CURRENT(‘tablename’) AS <IdentityColumnname>
inserted
tetapi tidak ada baris yang dimasukkan saatINSTEAD OF
pemicu.