SQL Server - INSERT 后返回值

发布于 2024-12-12 05:57:03 字数 207 浏览 0 评论 0原文

我试图在 INSERT 语句后获取键值。 例子: 我有一个包含属性名称和 ID 的表。 id 是生成的值。

    INSERT INTO table (name) VALUES('bob');

现在我想在同一步骤中取回 id。这是怎么做到的?

我们使用的是 Microsoft SQL Server 2008。

I'm trying to get a the key-value back after an INSERT-statement.
Example:
I've got a table with the attributes name and id. id is a generated value.

    INSERT INTO table (name) VALUES('bob');

Now I want to get the id back in the same step. How is this done?

We're using Microsoft SQL Server 2008.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

梓梦 2024-12-19 05:57:03

不需要单独的 SELECT...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

这也适用于非 IDENTITY 列(例如 GUID)

No need for a separate SELECT...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

This works for non-IDENTITY columns (such as GUIDs) too

迟月 2024-12-19 05:57:03

使用 SCOPE_IDENTITY() 获取新的 ID 值

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http: //msdn.microsoft.com/en-us/library/ms190315.aspx

Use SCOPE_IDENTITY() to get the new ID value

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx

爱的那么颓废 2024-12-19 05:57:03
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

这是最安全的选择,因为在带有触发器的表上存在 OUTPUT 子句冲突的已知问题。这使得这非常不可靠,因为即使您的表当前没有任何触发器 - 有人添加一个触发器也会破坏您的应用程序。定时炸弹之类的行为。

请参阅 msdn 文章以获取更深入的解释:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

Is the safest bet since there is a known issue with OUTPUT Clause conflict on tables with triggers. Makes this quite unreliable as even if your table doesn't currently have any triggers - someone adding one down the line will break your application. Time Bomb sort of behaviour.

See msdn article for deeper explanation:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

夜未央樱花落 2024-12-19 05:57:03

实体框架执行类似于 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 年,那你就不走运了。

Entity Framework performs something similar to gbn's answer:

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

The output results are stored in a temporary table variable, and then selected back to the client. Have to be aware of the gotcha:

inserts can generate more than one row, so the variable can hold more than one row, so you can be returned more than one ID

I have no idea why EF would inner join the ephemeral table back to the real table (under what circumstances would the two not match).

But that's what EF does.

SQL Server 2008 or newer only. If it's 2005 then you're out of luck.

请你别敷衍 2024-12-19 05:57:03

插入后退出的方式有很多种

向表中插入数据时,可以使用 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];

There are many ways to exit after insert

When you insert data into a table, you can use the OUTPUT clause to
return a copy of the data that’s been inserted into the table. The
OUTPUT clause takes two basic forms: OUTPUT and OUTPUT INTO. Use the
OUTPUT form if you want to return the data to the calling application.
Use the OUTPUT INTO form if you want to return the data to a table or
a table variable.

DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));

INSERT INTO tableName
(
  NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
   'test',...
)

IDENT_CURRENT: It returns the last identity created for a particular table or view in any session.

SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]

SCOPE_IDENTITY: It returns the last identity from a same session and the same scope. A scope is a stored procedure/trigger etc.

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  

@@IDENTITY: It returns the last identity from the same session.

SELECT @@IDENTITY AS [@@IDENTITY];
爱,才寂寞 2024-12-19 05:57:03

@@IDENTITY 是一个系统函数,返回最后插入的标识值。

@@IDENTITY Is a system function that returns the last-inserted identity value.

拿命拼未来 2024-12-19 05:57:03

有多种方法可以获取插入命令后最后插入的 ID。

  1. @@IDENTITY :它返回当前会话中连接上生成的最后一个 Identity 值,无论生成该值的表和语句范围如何
  2. SCOPE_IDENTITY():它返回无论表如何,当前连接的当前作用域中的 insert 语句生成的最后一个标识值。
  3. IDENT_CURRENT('TABLENAME') :它返回指定表上生成的最后一个标识值,无论任何连接、会话或范围如何。 IDENT_CURRENT不受范围和会话的限制;它仅限于指定的表。

现在似乎更难决定哪一个将完全符合我的要求。

我最喜欢 SCOPE_IDENTITY()。

如果您在 insert 语句中使用 select SCOPE_IDENTITY() 和 TableName,您将得到符合您期望的准确结果。

来源: CodoBee< /a>

There are multiple ways to get the last inserted ID after insert command.

  1. @@IDENTITY : It returns the last Identity value generated on a Connection in current session, regardless of Table and the scope of statement that produced the value
  2. SCOPE_IDENTITY(): It returns the last identity value generated by the insert statement in the current scope in the current connection regardless of the table.
  3. IDENT_CURRENT(‘TABLENAME’) : It returns the last identity value generated on the specified table regardless of Any connection, session or scope. IDENT_CURRENT is not limited by scope and session; it is limited to a specified table.

Now it seems more difficult to decide which one will be exact match for my requirement.

I mostly prefer SCOPE_IDENTITY().

If you use select SCOPE_IDENTITY() along with TableName in insert statement, you will get the exact result as per your expectation.

Source : CodoBee

濫情▎り 2024-12-19 05:57:03

最好、最可靠的解决方案是使用 SCOPE_IDENTITY()。

只是您必须在每次插入后获取范围标识并将其保存在变量中,因为您可以在同一范围内调用两个插入。

ident_current@@identity 可能有效,但它们不是安全范围。您可能会在大型应用程序中遇到问题

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

更多详细信息请参见微软文档

The best and most sure solution is using SCOPE_IDENTITY().

Just you have to get the scope identity after every insert and save it in a variable because you can call two insert in the same scope.

ident_current and @@identity may be they work but they are not safe scope. You can have issues in a big application

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

More detail is here Microsoft docs

彼岸花ソ最美的依靠 2024-12-19 05:57:03

您可以使用 scope_identity() 选择刚刚插入变量的行的 ID,然后只需从该表中选择您想要的任何列,其中 id = 您从 scope_identity( 获得的标识) )

请参阅此处获取 MSDN 信息 http://msdn.microsoft.com/en-us/library/ms190315.aspx

You can use scope_identity() to select the ID of the row you just inserted into a variable then just select whatever columns you want from that table where the id = the identity you got from scope_identity()

See here for the MSDN info http://msdn.microsoft.com/en-us/library/ms190315.aspx

怎会甘心 2024-12-19 05:57:03

推荐使用 SCOPE_IDENTITY() 来获取新的 ID 值,但使用“OUTPUT Inserted.ID”

如果插入语句抛出异常,我除外它直接抛出它。但“OUTPUT Inserted.ID”将返回 0,这可能与预期不符。

Recommend to use SCOPE_IDENTITY() to get the new ID value, But NOT use "OUTPUT Inserted.ID"

If the insert statement throw exception, I except it throw it directly. But "OUTPUT Inserted.ID" will return 0, which maybe not as expected.

诠释孤独 2024-12-19 05:57:03

已确认的答案对于 MS SQL Servers Transact-SQL 是正确的,但如果您想对 PostgreSQL 执行此操作,则需要使用 RETURNING 子句:

INSERT INTO table (name)
VALUES('bob')
RETURNING id;

The confirmed answer is correct for MS SQL Servers Transact-SQL, but if you'd want to do it for PostgreSQL, you would need to use the RETURNING clause:

INSERT INTO table (name)
VALUES('bob')
RETURNING id;
如梦 2024-12-19 05:57:03

您可以将 select 语句附加到 insert 语句中。

Integer myInt = 
Insert into table1 (FName) values('Fred'); Select Scope_Identity();

当执行标量时,这将返回一个身份值。

You can append a select statement to your insert statement.

Integer myInt = 
Insert into table1 (FName) values('Fred'); Select Scope_Identity();

This will return a value of the identity when executed scalar.

月依秋水 2024-12-19 05:57:03

这就是我在 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)

This is how I use OUTPUT INSERTED, when inserting to a table that uses ID as identity column in SQL Server:

'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)
千紇 2024-12-19 05:57:03

在对带有标识列的表进行插入操作后,您可以引用 @@IDENTITY 来获取值:
http://msdn.microsoft.com/en -us/library/aa933167%28v=sql.80%29.aspx

After doing an insert into a table with an identity column, you can reference @@IDENTITY to get the value:
http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx

橘虞初梦 2024-12-19 05:57:03

* 连接字符串中的参数顺序有时很重要。 * Provider 参数的位置可能会在添加行后破坏记录集游标。我们在 SQLOLEDB 提供程序中看到了这种行为。

添加行后,行字段不可用,除非将提供程序指定为连接字符串中的第一个参数。当提供程序位于连接字符串中除第一个参数之外的任何位置时,新插入的行字段不可用。当我们将 Provider 移至第一个参数时,行字段神奇地出现了。

* Parameter order in the connection string is sometimes important. * The Provider parameter's location can break the recordset cursor after adding a row. We saw this behavior with the SQLOLEDB provider.

After a row is added, the row fields are not available, UNLESS the Provider is specified as the first parameter in the connection string. When the provider is anywhere in the connection string except as the first parameter, the newly inserted row fields are not available. When we moved the the Provider to the first parameter, the row fields magically appeared.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文