GUID'ler için SCOPE_IDENTITY ()?


94

Biri bana SCOPE_IDENTITY()GUID'leri SQL Server'da birincil anahtar olarak kullanmanın bir eşdeğeri olup olmadığını söyleyebilir mi?

Öncelikle GUID oluşturmak ve birincil anahtarlarımız olarak sıralı GUID'leri kullandığımız için değişken olarak kaydetmek istemiyorum.

Son eklenen GUID birincil anahtarını almanın en iyi yolunun ne olduğuna dair bir fikriniz var mı?

Yanıtlar:


100

OUTPUT'u kullanarak GUID'i geri alabilirsiniz. Bu, birden çok kayıt eklediğinizde de çalışır.

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

Referans: SQL 2005'in OUTPUT Maddesini Keşfetme


2
Anishmarokey'in bahsettiği gibi, GUID'lerinizi oluşturmak için NewSequentialID () kullanmalısınız, NewID () kullanmamalısınız.
Rob Garrison

1
@RobGarrison Imo, bir PK olarak GUID, dağıtılmış sistemlerde yalnızca int / bigint'e göre gerçekten avantajlıdır. Bir ID almak için DB'ye vuruyorsanız, int / bigint de kullanabilirsiniz. NewSequentialID () yalnızca varsayılan bir kısıtlama olarak kullanılabilir (örneğin, NewSequentialID () kullanarak açıkça ekleyemezsiniz). Bunun gibi, sana senaryoları büyük çoğunluğunu düşünüyorum olabilir daha farklı zaten şeyler yapıyor olmalıdır kullanın.
Shiv

Yan OUTPUTtümce, ekli tetikleyici olan herhangi bir tabloda hata verir.
Cobus Kruger

62

GUID'leri birincil anahtar olarak kullanırken SCOPE_IDENTITY () eşdeğeri yoktur, ancak benzer bir sonuç elde etmek için OUTPUT yan tümcesini kullanabilirsiniz. Çıktı için bir tablo değişkeni kullanmanıza gerek yoktur.

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

GO

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

Bir .Net istemcisinden değeri okumak istiyorsanız yukarıdaki örnek kullanışlıdır. Net'ten değeri okumak için sadece ExecuteScalar yöntemini kullanmanız gerekir.

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

9

NEWID () kullanmak istiyorsun

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

    select @id

ancak kümelenmiş dizin sorunu GUID'de var. bunu da okuyun NEWSEQUENTIALID (). Bunlar benim fikirlerim, GUID'i birincil Anahtar olarak kullanmadan önce düşünün . :)


10
"Newsequentialid () yerleşik işlevi, yalnızca bir CREATE TABLE veya ALTER TABLE deyimindeki 'benzersiz tanımlayıcı' türündeki bir sütun için bir DEFAULT ifadesinde kullanılabilir. Karmaşık bir skaler ifade oluşturmak için diğer operatörlerle birleştirilemez."
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;

2

Bu iş parçacığını bir kaynak olarak kullanarak, aşağıdakileri bir tetikleyicide kullanmak için oluşturdum:

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;

Bir başkasının aynı şeyi yapmasına yardımcı olabilir. Bu iyi bir fikir değilse veya değilse performans açısından akıllıca söyleyecek kötü bir şeyi olup olmadığını merak ediyorum.


soruyu tekrar okuduktan sonra, bunun kullanıcıların sorusuna gerçekten cevap vermediğini fark ettim ... ama yine de birine yardımcı olabilir çünkü benzer cevaplar aynı tip cevaplardır.
TravisWhidden
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.