2009-10-02 13 views
80

¿Alguien puede decirme si hay un equivalente de SCOPE_IDENTITY() al usar GUID como clave principal en SQL Server?SCOPE_IDENTITY() para GUID?

No quiero crear primero el GUID y guardarlo como una variable ya que estamos utilizando GUID secuenciales como nuestras claves principales.

¿Alguna idea sobre cuál es la mejor forma de recuperar la última clave principal GUID insertada?

Respuesta

6

que desea utilizar NEWID()

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

    select @id 

pero el problema índice agrupado con los que cuenta GUID. lea esto también NEWSEQUENTIALID(). Estas son mis ideas, piense antes de usar el GUID como primary Key. :)

+0

+1 para NEWSEQUENTIALID –

+5

"La función incorporada newsequentialid() solo se puede usar en una expresión DEFAULT para una columna de tipo 'uniqueidentifier' en una instrucción CREATE TABLE o ALTER TABLE. No se puede combinar con otros operadores para formar una expresión escalar compleja ". –

82

Puede recuperar el GUID utilizando OUTPUT. Esto funciona cuando también está insertando varios registros.

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 

Referencia: Exploring SQL 2005’s OUTPUT Clause

+1

Como menciona anishmarokey, debe utilizar NewSequentialID() para generar sus GUID y no NewID(). –

+0

Gracias, no tenía ni idea sobre la sintaxis – cmsjr

3
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; 
47

No hay SCOPE_IDENTITY() equivalente al utilizar GUID como claves primarias, pero se puede utilizar la cláusula OUTPUT para lograr un resultado similar. No necesita usar una variable de tabla para la salida.

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

GO 

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

El ejemplo anterior es útil si desea leer el valor de un cliente .Net. Para leer el valor de .Net, simplemente usaría el método ExecuteScalar.

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

El uso de este hilo como un recurso, he creado la siguiente información para su uso dentro de un disparador:

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; 

podría ayudar a otra persona a hacer lo mismo. Es curioso si alguien tiene algo malo que decir respecto al rendimiento si no es una buena idea o no.

+0

después de volver a leer la pregunta, me di cuenta de que esto realmente no responde a la pregunta de los usuarios ... pero aún podría ser útil para alguien porque las respuestas similares son del mismo tipo. – TravisWhidden