在多线程环境中的 SQL Server 中插入后获取 Id?

发布于 2024-09-27 16:52:20 字数 136 浏览 5 评论 0原文

在 SQL Server 中插入后如何获取 id?

对于我的插入,我使用 context.ExecuteStoreCommand()

警告:我有一个多线程应用程序,它“同时”在同一个表中插入一些数据。

How can I get id after an INSERT in SQL Server ?

For my insert, I use context.ExecuteStoreCommand()

Warning: I have a multi-threaded application which inserts "at the same time" some data in the same table.

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

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

发布评论

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

评论(8

舟遥客 2024-10-04 16:52:20
SELECT SCOPE_IDENTITY()

在插入语句之后使用它,它将返回您范围中插入的标识。您可以将其分配给变量或在输出参数中返回它。

SELECT SCOPE_IDENTITY()

Use this after your insert statement and it will return you the identity of inserted in your scope. You can assign this to variable or return it in an output parameter.

安稳善良 2024-10-04 16:52:20

对于这种情况,您应该使用 Scope_Identity()。这将返回当前范围的身份。 @@Identity 返回最后插入的身份。

查看 MSDN 上的 Scope Identity - 有一些示例说明<与使用 Scope_Identity 相比,code>@@Identity 将返回不正确的值

You should use Scope_Identity() for this scenario. This will return the Identity for the current scope. @@Identity returns the last inserted identity.

Take a look at Scope Identity on MSDN - there are examples of how @@Identity will return incorrect values compared to using Scope_Identity

铁憨憨 2024-10-04 16:52:20

尝试

@@identity

下面的示例代码

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT @@Identity"
SQLCommand.CommandText = strSQL
Id = SQLCommand.ExecuteScalar()

Try this

@@identity

below the sample code

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT @@Identity"
SQLCommand.CommandText = strSQL
Id = SQLCommand.ExecuteScalar()
jJeQQOZ5 2024-10-04 16:52:20

另一种实现方法是使用 OUTPUT 子句。

例如:

create table #tmpTable 
(
    ID int identity(1,1) not null primary key,
    SomeValue varchar(20) not null
);

insert #tmpTable
output INSERTED.ID
values('SomeTextData')

drop table #tmpTable;

从整体解决方案设计的角度来看,我建议您将插入逻辑包装到从应用程序源代码调用的存储过程(返回插入的记录 ID)中。

An alternative implementation method is to use the OUTPUT clause of the T-SQL language.

For example:

create table #tmpTable 
(
    ID int identity(1,1) not null primary key,
    SomeValue varchar(20) not null
);

insert #tmpTable
output INSERTED.ID
values('SomeTextData')

drop table #tmpTable;

From an overall solution design perspective I would advocate that you look to wrap your insertion logic into a Stored Procedure (returning the inserted record ID) that you call from your application source code.

对风讲故事 2024-10-04 16:52:20

我认为您可以编写一个具有输入/输出参数的存储过程,然后从参数中获取值。

I think you can write up a stored proc which has an in/out parameter, and then grab the value from the parameter.

忆梦 2024-10-04 16:52:20

我相当确定您会想要使用 ObjectContext.ExecuteStoreQuery方法(如果您需要标识值),而不是 ObjectContext .ExecuteStoreCommand

正如其他人提到的那样,您需要使用 SCOPE_IDENTITY(),而不是 @@IDENTITY,因为 SCOPE_IDENTITY() 返回以下内容的标识值当前执行范围是 @@IDENTITY “是一个返回最后插入的标识值的系统函数。”

像这样的事情应该可以解决问题:

using(var context = GetAContextThatsReadyToUse())
{
    var valueForColumn1 = 5;
    var result = ExecuteStoreQuery<int>("INSERT INTO table1 (Column1) VALUES ({0});SELECT SCOPE_IDENTITY()", valueForColumn1);

    foreach(var item in result)
    {
        // Should only return one result, which is the identity value inserted by ExecuteStoreQuery
        Console.WriteLine(item);
    }
}

I'm fairly sure you'll want to use the ObjectContext.ExecuteStoreQuery method if you need the identity value, rather than ObjectContext.ExecuteStoreCommand.

You'll need to use, as others have mentioned SCOPE_IDENTITY(), rather than @@IDENTITY as SCOPE_IDENTITY() returns the identity value for the currente execution scope wheras @@IDENTITY "Is a system function that returns the last-inserted identity value."

Something like this should do the trick:

using(var context = GetAContextThatsReadyToUse())
{
    var valueForColumn1 = 5;
    var result = ExecuteStoreQuery<int>("INSERT INTO table1 (Column1) VALUES ({0});SELECT SCOPE_IDENTITY()", valueForColumn1);

    foreach(var item in result)
    {
        // Should only return one result, which is the identity value inserted by ExecuteStoreQuery
        Console.WriteLine(item);
    }
}
旧梦荧光笔 2024-10-04 16:52:20

我遇到过很多情况,一次有 100 个进程在一张表上写入。我没有使用 SCOPE_IDENTITY() ,而是将整个插入/ID 获取包装到事务中,并且该方法没有任何问题。

I had lot of situations where something like 100 processes were writing at one table at a time. I didn't use SCOPE_IDENTITY() but were wrapping whole insert/ID fetch into an transaction, and there wasn't any problem with that approach.

茶色山野 2024-10-04 16:52:20

请参阅 SQL Server - INSERT 后返回值

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

refer SQL Server - Return value after INSERT

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