GUID 的 SCOPE_IDENTITY() ?

有人能告诉我在 SQLServer 中使用 GUID 作为主键时是否有相当于 SCOPE_IDENTITY()的东西吗?

我不想首先创建 GUID 并保存为一个变量,因为我们使用顺序 GUID 作为主键。

对于检索最后插入的 GUID 主键的最佳方法有什么想法吗?

63195 次浏览

you want to use NEWID()

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


select @id

but clustered index problem are there in GUID . read this one tooNEWSEQUENTIALID() .These are my ideas ,think before use GUID as primary Key . :)

You can get the GUID back by using OUTPUT. This works when you're inserting multiple records also.

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

Reference: Exploring SQL 2005’s OUTPUT Clause

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;

There is no SCOPE_IDENTITY() equivalent when using GUIDs as primary keys, but you can use the OUTPUT clause to achieve a similar result. You don't need to use a table variable for 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)

The example above is useful if you want to read the value from a .Net client. To read the value from .Net you would just use the ExecuteScalar method.

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

Using this thread as a resource, I created the following for use within a 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;

Might help someone else doing the same thing. Curious if anyone has anything bad to say performance wise if this is not a good idea or not.