Pertanyaan Cara terbaik untuk mendapatkan identitas dari baris yang dimasukkan?


Apa cara terbaik untuk mendapatkannya IDENTITY dari baris yang dimasukkan?

Saya tahu tentang @@IDENTITY dan IDENT_CURRENT dan SCOPE_IDENTITY tetapi tidak memahami pro dan kontra yang melekat pada masing-masing.

Bisakah seseorang menjelaskan perbedaannya dan kapan saya harus menggunakannya?


889
2017-09-03 21:32


asal


Jawaban:


  • @@IDENTITY mengembalikan nilai identitas terakhir yang dihasilkan untuk tabel apa pun dalam sesi saat ini, di semua cakupan. Anda harus berhati-hati di sini, karena itu di luar jangkauan. Anda bisa mendapatkan nilai dari pemicu, bukan pernyataan Anda saat ini.

  • SCOPE_IDENTITY() mengembalikan nilai identitas terakhir yang dihasilkan untuk setiap tabel dalam sesi saat ini dan ruang lingkup saat ini. Umumnya apa yang ingin Anda gunakan.

  • IDENT_CURRENT('tableName') mengembalikan nilai identitas terakhir yang dihasilkan untuk tabel spesifik di setiap sesi dan cakupan apa pun. Ini memungkinkan Anda menentukan tabel mana yang Anda inginkan nilainya, jika dua di atas tidak cukup yang Anda perlukan (sangat langka). Juga, seperti @Guy Starbuck disebutkan, "Anda bisa menggunakan ini jika Anda ingin mendapatkan nilai IDENTITAS saat ini untuk tabel yang belum Anda masukkan catatan."

  • Itu OUTPUT ayat dari INSERT Pernyataan akan memungkinkan Anda mengakses setiap baris yang disisipkan melalui pernyataan itu. Karena itu mencakup pernyataan spesifik, itu lebih mudah dari fungsi-fungsi lain di atas. Namun, itu sedikit lebih banyak verbose (Anda harus memasukkan ke dalam tabel variabel variabel / temp dan kemudian query itu) dan itu memberikan hasil bahkan dalam skenario kesalahan di mana pernyataan itu digulung kembali. Yang mengatakan, jika permintaan Anda menggunakan rencana eksekusi paralel, ini adalah hanya metode jaminan untuk mendapatkan identitas (singkat mematikan paralelisme). Namun, itu dijalankan sebelum pemicu dan tidak dapat digunakan untuk mengembalikan nilai yang dihasilkan pemicu.


1171
2017-09-03 21:38



Saya percaya metode paling aman dan paling akurat untuk mengambil id yang disisipkan adalah dengan menggunakan klausa output.

misalnya (diambil dari yang berikut ini MSDN artikel)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

150
2018-05-20 14:43



Saya mengatakan hal yang sama dengan orang lain, jadi semua orang benar, saya hanya berusaha membuatnya lebih jelas.

@@IDENTITY mengembalikan id dari hal terakhir yang disisipkan oleh koneksi klien Anda ke database.
Sebagian besar waktu ini berfungsi dengan baik, tetapi terkadang pemicu akan pergi dan menyisipkan baris baru yang tidak Anda ketahui, dan Anda akan mendapatkan ID dari baris baru ini, bukan yang Anda inginkan

SCOPE_IDENTITY() memecahkan masalah ini. Ia mengembalikan id dari hal terakhir itu Anda dimasukkan dalam kode SQL kamu mengirim ke database. Jika pemicu pergi dan membuat baris tambahan, mereka tidak akan menyebabkan nilai yang salah untuk dikembalikan. Hore

IDENT_CURRENT mengembalikan ID terakhir yang disisipkan oleh siapa pun. Jika beberapa aplikasi lain terjadi untuk memasukkan baris lain pada waktu yang tidak tepat, Anda akan mendapatkan ID dari baris tersebut bukan baris Anda.

Jika Anda ingin memainkannya dengan aman, selalu gunakan SCOPE_IDENTITY(). Jika Anda tetap dengan @@IDENTITYdan seseorang memutuskan untuk menambahkan pemicu nanti, semua kode Anda akan rusak.


94
2017-09-03 21:44



Cara terbaik (baca: teraman) untuk mendapatkan identitas baris yang baru dimasukkan adalah dengan menggunakan output ayat:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

52
2018-04-29 07:22



Menambahkan

SELECT CAST(scope_identity() AS int);

ke akhir pernyataan masukkan sql Anda, lalu

NewId = command.ExecuteScalar()

akan mengambilnya.


20
2018-03-30 18:25



MSDN

@@ IDENTITY, SCOPE_IDENTITY, dan IDENT_CURRENT adalah fungsi serupa karena mengembalikan nilai terakhir yang dimasukkan ke dalam kolom IDENTITAS pada tabel.

@@ IDENTITY dan SCOPE_IDENTITY akan mengembalikan nilai identitas terakhir yang dihasilkan di tabel mana pun dalam sesi saat ini. Namun, SCOPE_IDENTITY mengembalikan nilai hanya dalam lingkup saat ini; @@ IDENTITY tidak terbatas pada cakupan tertentu.

IDENT_CURRENT tidak dibatasi oleh cakupan dan sesi; itu terbatas pada tabel yang ditentukan. IDENT_CURRENT mengembalikan nilai identitas yang dihasilkan untuk tabel tertentu di setiap sesi dan ruang lingkup apa pun. Untuk informasi lebih lanjut, lihat IDENT_CURRENT.

  • IDENT_CURRENT adalah fungsi yang mengambil meja sebagai argumen.
  • @@IDENTITAS dapat mengembalikan hasil yang membingungkan ketika Anda memiliki pemicu di atas meja
  • SCOPE_IDENTITY adalah pahlawan Anda sebagian besar waktu.

12
2017-09-03 21:37



@@IDENTITAS adalah identitas terakhir yang dimasukkan menggunakan Koneksi SQL saat ini. Ini adalah nilai yang baik untuk kembali dari prosedur insert yang tersimpan, di mana Anda hanya perlu identitas yang dimasukkan untuk catatan baru Anda, dan tidak peduli jika lebih banyak baris ditambahkan sesudahnya.

SCOPE_IDENTITY adalah identitas terakhir yang dimasukkan menggunakan Koneksi SQL saat ini, dan dalam lingkup saat ini - yaitu, jika ada IDENTITAS kedua yang disisipkan berdasarkan pemicu setelah penyisipan Anda, itu tidak akan tercermin dalam SCOPE_IDENTITY, hanya insert yang Anda lakukan. Terus terang, saya tidak pernah punya alasan untuk menggunakan ini.

IDENT_CURRENT (tablename) adalah identitas terakhir yang dimasukkan terlepas dari koneksi atau ruang lingkup. Anda bisa menggunakan ini jika Anda ingin mendapatkan nilai IDENTITAS saat ini untuk tabel yang belum Anda masukkan catatan.


11
2017-09-03 21:42