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.