SCOPE_IDENTITY () per GUID?


94

Qualcuno può dirmi se esiste un equivalente di SCOPE_IDENTITY()quando si utilizzano i GUID come chiave primaria in SQL Server?

Non voglio creare prima il GUID e salvarlo come variabile poiché utilizziamo GUID sequenziali come chiavi primarie.

Qualche idea su quale sia il modo migliore per recuperare l'ultima chiave primaria GUID inserita?

Risposte:


98

È possibile recuperare il GUID utilizzando OUTPUT. Funziona anche quando inserisci più record.

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

Riferimento: esplorazione della clausola OUTPUT di SQL 2005


2
Come menzionato da anishmarokey, dovresti usare NewSequentialID () per generare i tuoi GUID e non NewID ().
Rob Garrison

@ RobGarrison Imo, GUID come PK è davvero vantaggioso solo su int / bigint nei sistemi distribuiti. Se stai premendo il DB per recuperare un ID, potresti anche usare int / bigint. NewSequentialID () può essere utilizzato solo come vincolo predefinito (non è possibile inserire esplicitamente utilizzando NewSequentialID () ad esempio). In quanto tale, penso che la stragrande maggioranza degli scenari in cui puoi usarlo dovresti comunque fare le cose in modo diverso.
Shiv

La OUTPUTclausola restituisce un errore su qualsiasi tabella a cui è collegato un trigger di inserimento.
Cobus Kruger

60

Non esiste un equivalente SCOPE_IDENTITY () quando si utilizzano i GUID come chiavi primarie, ma è possibile utilizzare la clausola OUTPUT per ottenere un risultato simile. Non è necessario utilizzare una variabile di tabella per l'output.

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

GO

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

L'esempio sopra è utile se vuoi leggere il valore da un client .Net. Per leggere il valore da .Net dovresti semplicemente usare il metodo ExecuteScalar.

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

9

vuoi usare NEWID ()

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

    select @id

ma il problema dell'indice cluster è presente nel GUID. leggi anche questo NEWSEQUENTIALID () .Queste sono le mie idee, pensa prima di usare GUID come chiave primaria . :)


10
"La funzione incorporata newsequentialid () può essere utilizzata solo in un'espressione DEFAULT per una colonna di tipo 'uniqueidentifier' in un'istruzione CREATE TABLE o ALTER TABLE. Non può essere combinata con altri operatori per formare un'espressione scalare complessa."
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

Utilizzando questo thread come risorsa, ho creato quanto segue da utilizzare all'interno di un trigger:

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;

Potrebbe aiutare qualcun altro a fare la stessa cosa. Curioso se qualcuno ha qualcosa di negativo da dire in termini di prestazioni se questa non è una buona idea o no.


dopo aver riletto la domanda, mi sono reso conto che questo in realtà non risponde alla domanda degli utenti ... ma potrebbe comunque essere utile a qualcuno perché le risposte simili sono lo stesso tipo di risposta.
TravisWhidden
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.