我应该如何获得插入行的身份?

我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。

谁能解释一下它们的区别,以及我什么时候使用它们?


当前回答

在你的插入语句之后,你需要添加这个。确认插入数据的表名。您将得到当前行,而不是刚才插入语句所影响的行。

IDENT_CURRENT('tableName')

其他回答

我不能与其他版本的SQL Server对话,但在2012年,直接输出工作得很好。您不需要为临时表而烦恼。

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

顺便说一下,这种技术也适用于插入多行。

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

输出

ID
2
3
4

我认为检索插入的id最安全、最准确的方法是使用output子句。

例如(摘自以下MSDN文章)

使用AdventureWorks2008R2; 去 声明@MyTableVar表(NewScrapReasonID smallint, 名字varchar (50), ModifiedDate datetime); 插入生产。ScrapReason 输出插入。ScrapReasonID,插入。名字,插入。ModifiedDate 到@MyTableVar VALUES (N'操作符错误',GETDATE()); ——显示表变量的结果集。 SELECT NewScrapReasonID, Name, ModifiedDate FROM @ mytablear; ——显示表的结果集。 SELECT ScrapReasonID, Name, ModifiedDate 从Production.ScrapReason; 去

另一种保证所插入行的身份的方法是指定身份值,并使用SET IDENTITY_INSERT ON和OFF。这保证了您确切地知道标识值是什么!只要这些值没有被使用,就可以将这些值插入到标识列中。

CREATE TABLE #foo 
  ( 
     fooid   INT IDENTITY NOT NULL, 
     fooname VARCHAR(20) 
  ) 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (1, 
             'one'), 
            (2, 
             'Two') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

INSERT INTO #foo 
            (fooname) 
VALUES      ('Three') 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

-- YOU CAN INSERT  
SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (10, 
             'Ten'), 
            (11, 
             'Eleven') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SELECT * 
FROM   #foo 

如果您正在从另一个数据源加载数据或合并来自两个数据库的数据等,这可能是一个非常有用的技术。

创建一个uuid并将其插入到列中。然后,您可以很容易地用uuid标识行。这是唯一可以实现的100%有效的解决方案。所有其他的解都太复杂了,或者在相同的边缘情况下不起作用。 例如:

1)创建行

INSERT INTO table (uuid, name, street, zip) 
        VALUES ('2f802845-447b-4caa-8783-2086a0a8d437', 'Peter', 'Mainstreet 7', '88888');

2)获取创建行

SELECT * FROM table WHERE uuid='2f802845-447b-4caa-8783-2086a0a8d437';

总是使用scope_identity(),永远不需要其他任何东西。