SCOPE_IDENTITY () untuk GUID?

94

Adakah yang bisa memberi tahu saya jika ada yang setara dengan SCOPE_IDENTITY()saat menggunakan GUID sebagai kunci utama di SQL Server?

Saya tidak ingin membuat GUID terlebih dahulu dan menyimpannya sebagai variabel karena kami menggunakan GUID berurutan sebagai kunci utama kami.

Adakah ide tentang cara terbaik untuk mengambil kunci utama GUID yang terakhir dimasukkan?

bplus
sumber

Jawaban:

98

Anda bisa mendapatkan kembali GUID dengan menggunakan OUTPUT. Ini juga berfungsi saat Anda memasukkan beberapa rekaman.

CREATE TABLE dbo.GuidPk (
    ColGuid uniqueidentifier NOT NULL DEFAULT NewSequentialID(),
    Col2    int              NOT NULL
)
GO

DECLARE @op TABLE (
    ColGuid uniqueidentifier
)

INSERT INTO dbo.GuidPk (
    Col2
)
OUTPUT inserted.ColGuid
INTO @op
VALUES (1)

SELECT * FROM @op

SELECT * FROM dbo.GuidPk

Referensi: Menjelajahi Klausul OUTPUT SQL 2005

Rob Garrison
sumber
2
Seperti yang disebutkan anishmarokey, Anda harus menggunakan NewSequentialID () untuk membuat GUID, bukan NewID ().
Rob Garrison
@RobGarrison Imo, GUID sebagai PK hanya benar-benar menguntungkan dibandingkan int / bigint dalam sistem terdistribusi. Jika Anda menekan DB untuk mengambil ID, Anda mungkin juga menggunakan int / bigint. NewSequentialID () hanya dapat digunakan sebagai batasan default (Anda tidak dapat menyisipkan secara eksplisit menggunakan NewSequentialID () misalnya). Karena itu, saya pikir sebagian besar skenario di mana Anda dapat menggunakannya, Anda harus melakukan hal-hal yang berbeda.
Shiv
The OUTPUTklausul memberikan kesalahan pada setiap meja yang memiliki pemicu insert yang terpasang.
Cobus Kruger
60

Tidak ada SCOPE_IDENTITY () yang setara saat menggunakan GUID sebagai kunci utama, tetapi Anda dapat menggunakan klausa OUTPUT untuk mendapatkan hasil yang serupa. Anda tidak perlu menggunakan variabel tabel untuk keluaran.

CREATE TABLE dbo.GuidTest (
    GuidColumn uniqueidentifier NOT NULL DEFAULT NewSequentialID(),
    IntColumn int NOT NULL
)

GO

INSERT INTO GuidTest(IntColumn)
OUTPUT inserted.GuidColumn
VALUES(1)

Contoh di atas berguna jika Anda ingin membaca nilai dari klien .Net. Untuk membaca nilai dari .Net Anda hanya akan menggunakan metode ExecuteScalar.

...
string sql = "INSERT INTO GuidTest(IntColumn) OUTPUT inserted.GuidColumn VALUES(1)";
SqlCommand cmd = new SqlCommand(sql, conn);
Guid guid = (Guid)cmd.ExecuteScalar();
...
Daniel
sumber
9

Anda ingin menggunakan NEWID ()

    declare @id uniqueidentifier
    set @id  = NEWID()
    INSERT INTO [dbo].[tbl1]
           ([id])
     VALUES
           (@id)

    select @id

tetapi masalah indeks berkerumun ada di GUID. baca yang ini juga NEWSEQUENTIALID () . Ini ide saya, pikirkan sebelum menggunakan GUID sebagai kunci utama . :)

anishMarokey
sumber
10
"Fungsi bawaan newsequentialid () hanya dapat digunakan dalam ekspresi DEFAULT untuk kolom berjenis 'uniqueidentifier' dalam pernyataan CREATE TABLE atau ALTER TABLE. Ini tidak dapat digabungkan dengan operator lain untuk membentuk ekspresi skalar yang kompleks."
Scott Whitlock
4
CREATE TABLE TestTable(KEY uniqueidentifier, ID VARCHAR(100), Name VARCHAR(100), Value tinyint);
Declare @id uniqueidentifier ;  
DECLARE @TmpTable TABLE (KEY uniqueidentifier);     
INSERT INTO [dbo].[TestTable]
    ([ID], [Name], Value])           
    OUTPUT INSERTED.KEY INTO @TmpTable           
    VALUES(@ID, @Name, @Value);           
SELECT @uniqueidentifier = KEY FROM @TmpTable; 
DROP TABLE TestTable;
Joe
sumber
2

Menggunakan utas ini sebagai sumber daya, saya membuat yang berikut ini untuk digunakan dalam pemicu:

DECLARE @nextId uniqueIdentifier;
DECLARE @tempTable TABLE(theKey uniqueIdentifier NOT NULL DEFAULT NewSequentialID(), b int);
INSERT INTO @tempTable (b) Values(@b);
SELECT @nextId = theKey from @tempTable;

Mungkin membantu orang lain melakukan hal yang sama. Penasaran apakah ada yang mengatakan hal buruk tentang kinerja, apakah ini bukan ide yang baik atau tidak.

TravisWhidden
sumber
setelah membaca ulang pertanyaan, saya menyadari ini benar-benar tidak menjawab pertanyaan pengguna ... tetapi masih dapat membantu seseorang karena jawaban yang serupa adalah jenis tanggapan yang sama.
TravisWhidden