我试图在INSERT语句之后得到一个键值。 例: 我有一个包含属性name和id的表。 id是生成的值。
INSERT INTO table (name) VALUES('bob');
现在我想在同一步骤中恢复身份。这是怎么做到的?
我们正在使用Microsoft SQL Server 2008。
答案 0 :(得分:409)
无需单独的SELECT ...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
这也适用于非IDENTITY列(例如GUID)
答案 1 :(得分:161)
使用SCOPE_IDENTITY()
获取新的ID值
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
答案 2 :(得分:37)
INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
是最安全的赌注,因为在带触发器的表上存在OUTPUT子句冲突的已知问题。这使得这非常不可靠,即使您的表当前没有任何触发器 - 有人在线下添加一个会破坏您的应用程序。时间炸弹的行为。
有关更深入的解释,请参阅msdn文章:
答案 3 :(得分:23)
实体框架执行类似于gbn的答案:
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');
SELECT t.[CustomerID]
FROM @generated_keys AS g
JOIN dbo.Customers AS t
ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0
输出结果存储在临时表变量中,然后选择回客户端。必须要知道问题:
插入可以生成多行,因此变量可以包含多行,因此可以返回多个
ID
我不知道为什么EF会将短暂的表连接回真实表(在什么情况下两者不匹配)。
但那是EF的作用。
仅限SQL Server 2008或更新版本。如果是2005年那么你就不幸了。
答案 4 :(得分:10)
@@ IDENTITY是一个返回最后插入的标识值的系统函数。
答案 5 :(得分:4)
您可以使用scope_identity选择刚刚插入变量的行的ID,然后从该表中选择您想要的任何列,其中id =您从scope_identity获得的身份
请在此处查看MSDN信息http://msdn.microsoft.com/en-us/library/ms190315.aspx
答案 6 :(得分:3)
最好,最确定的解决方案是使用SCOPE_IDENTITY。 只是您必须在每次插入后获取作用域标识并将其保存在变量中,因为您可以在同一作用域中调用两个insert。 @identity和@@ identity可能起作用,但它们不是安全范围。您可能在大型应用程序中遇到问题
declare @duplicataId int
select @duplicataId = (SELECT SCOPE_IDENTITY())
更多详细信息在这里Microsoft docs
答案 7 :(得分:1)
插入后有多种退出方式
将数据插入表中时,可以使用OUTPUT子句来 返回已插入表中的数据的副本。的 OUTPUT子句采用两种基本形式:OUTPUT和OUTPUT INTO。使用 如果要将数据返回到调用应用程序,请使用OUTPUT表格。 如果要将数据返回到表中,请使用OUTPUT INTO表单。 表变量。
DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));
INSERT INTO tableName
(
NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
'test',...
)
IDENT_CURRENT :它返回在任何会话中为特定表或视图创建的最后一个身份。
SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]
SCOPE_IDENTITY :它返回来自同一会话和相同范围的最后一个身份。范围是存储过程/触发器等。
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
@@ IDENTITY :它返回同一会话中的最后一个身份。
SELECT @@IDENTITY AS [@@IDENTITY];
答案 8 :(得分:1)
有多种方法可以在插入命令后获取最后插入的ID。
@@IDENTITY
:无论当前表和生成该值的语句范围如何,它都会返回当前会话中在Connection上生成的最后一个Identity值SCOPE_IDENTITY()
:它返回在当前连接的当前作用域中,由insert语句生成的最后一个标识值,与表无关。IDENT_CURRENT(‘TABLENAME’)
:无论指定任何连接,会话或作用域,它都会返回在指定表上生成的最后一个标识值。 IDENT_CURRENT不受范围和会话的限制;它仅限于指定的表。 现在,要确定哪一个与我的需求完全匹配似乎更加困难。
我最喜欢SCOPE_IDENTITY()。
如果在insert语句中将select SCOPE_IDENTITY()与TableName一起使用,则将按照您的期望获得准确的结果。
来源:CodoBee
答案 9 :(得分:1)
推荐使用SCOPE_IDENTITY()来获取新的ID值,但不要使用“OUTPUT Inserted.ID”
如果insert语句抛出异常,我除了直接抛出。但是“OUTPUT Inserted.ID”将返回0,这可能不是预期的。
答案 10 :(得分:0)
当我在SQL Server中插入使用ID作为标识列的表时,这就是我使用OUTPUT INSERTED的方式:
'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
答案 11 :(得分:0)
您可以在insert语句中附加select语句。 整数myInt = 插入table1(FName)值('Fred');选择Scope_Identity(); 这将在执行scaler时返回标识值。
答案 12 :(得分:-2)
*连接字符串中的参数顺序有时很重要。 * Provider参数的位置可以在添加行后中断记录集游标。我们在SQLOLEDB提供程序中看到了这种行为。
添加行后,行字段不可用,除非在连接字符串中将Provider指定为第一个参数。当提供程序位于连接字符串中的任何位置时(第一个参数除外),新插入的行字段不可用。当我们将Provider移动到第一个参数时,行字段神奇地出现了。
答案 13 :(得分:-3)
这可能有点老套了,但是有很多人在使用较旧的PHP,Pre 5.5或更精确。更多详细信息,请访问http://php.net/manual/en/function.mysql-insert-id.php
$last = mysql_insert_id();
答案 14 :(得分:-5)
在插入带有标识列的表后,您可以引用@@ IDENTITY来获取值: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx