用于GUID的SCOPE_IDENTITY()?


94

谁能告诉我SCOPE_IDENTITY()在SQL Server中使用GUID作为主键时是否等效?

我不想先创建GUID并另存为变量,因为我们将顺序GUID用作主键。

是否有什么最佳方法来检索最后插入的GUID主键?

Answers:


98

您可以使用OUTPUT重新获得GUID。当您还要插入多个记录时,此方法也有效。

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

参考:探索SQL 2005的OUTPUT子句


2
如anishmarokey所述,您应该使用NewSequentialID()而不是NewID()来生成GUID。
罗布·加里森

@RobGarrison Imo,GUID作为PK仅在分布式系统中真正优于int / bigint。如果您要访问数据库以获取ID,则最好使用int / bigint。NewSequentialID()只能用作默认约束(例如,您不能使用NewSequentialID()显式插入)。因此,我认为您可以使用它的绝大多数情况下,您的操作应该有所不同。
Shiv

OUTPUT子句会在任何附加了插入触发器的表上给出错误。
Cobus Kruger

60

使用GUID作为主键时,没有等效的SCOPE_IDENTITY(),但是您可以使用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)

如果要从.Net客户端读取值,则上面的示例很有用。要从.Net读取值,您只需使用ExecuteScalar方法。

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

9

您想使用NEWID()

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

    select @id

但是GUID中存在聚集索引问题。我也想读这个NEWSEQUENTIALID()。这些是我的想法,请先考虑使用GUID作为主键。:)


10
“ newsequentialid()内置函数只能在CREATE TABLE或ALTER TABLE语句中的'uniqueidentifier'类型的列的DEFAULT表达式中使用。不能与其他运算符组合以形成复杂的标量表达式。”
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

使用此线程作为资源,我创建了以下内容供触发器使用:

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;

可能会帮助别人做同样的事情。如果这不是一个好主意,是否有人对性能有不好的说法感到好奇。


重新阅读问题后,我意识到这确实无法回答用户的问题...但是对某人还是有帮助的,因为相似的答案是相同类型的响应。
TravisWhidden
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.