如何在调用 exec(@Sql) 后获取身份值

发布于 2024-08-22 08:25:04 字数 1032 浏览 4 评论 0原文

我试图找到 exec(@Sql) 插入的插入记录的标识值,但 exec() 似乎在不同的范围内执行。

/*
create table [dbo].[__Test](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [description] [varchar](100) NULL
) ON [PRIMARY]
GO
*/

declare @Sql varchar(512)
set @Sql = 'insert into [dbo].[__Test] ([description]) values (''Some text'')'
exec (@Sql)

select
    @@IDENTITY as [@@IDENTITY],
    scope_identity() as [scope_identity],
    ident_current('__Test') as [ident_current]

/*  
if exists(select * from sys.objects where object_id = object_id('[dbo].[__Test]') and type='U')
    drop table [dbo].[__Test]
GO
*/

返回:

@@IDENTITY  scope_identity  ident_current
----------  --------------  -------------
14          NULL            14

如果 __Test 上有触发器,则返回:

@@IDENTITY  scope_identity  ident_current
----------  --------------  -------------
6           NULL            14

因此 @@IDENTITY 可能是触发器插入,执行不在范围内,并且 ident_current() 可能来自另一个用户。

有没有什么方法可以从 exec() 所做的插入中可靠地找到标识值?

I am trying to find the identity value of an inserted record inserted by exec(@Sql), but it seems that exec() excutes in a different scope.

/*
create table [dbo].[__Test](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [description] [varchar](100) NULL
) ON [PRIMARY]
GO
*/

declare @Sql varchar(512)
set @Sql = 'insert into [dbo].[__Test] ([description]) values (''Some text'')'
exec (@Sql)

select
    @@IDENTITY as [@@IDENTITY],
    scope_identity() as [scope_identity],
    ident_current('__Test') as [ident_current]

/*  
if exists(select * from sys.objects where object_id = object_id('[dbo].[__Test]') and type='U')
    drop table [dbo].[__Test]
GO
*/

returns:

@@IDENTITY  scope_identity  ident_current
----------  --------------  -------------
14          NULL            14

and if there is a trigger on __Test, returns:

@@IDENTITY  scope_identity  ident_current
----------  --------------  -------------
6           NULL            14

So @@IDENTITY could be a trigger insert, the execution is not in scope and ident_current() could be from another user.

Is there any way of reliably finding the identity value from an insert made by exec()?

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

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

发布评论

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

评论(2

我恋#小黄人 2024-08-29 08:25:04

是的,通过使用 sp_executesql:

DECLARE @nSQL NVARCHAR(500)
DECLARE @NewID INTEGER

SET @nSQL = 'INSERT MyTable (MyField) VALUES (123) SELECT @NewID = SCOPE_IDENTITY()'
EXECUTE sp_executesql @nSQL, N'@NewID INTEGER OUTPUT', @NewId OUTPUT

--@NewId now contains the ID

sp_executesql 的优点是您可以参数化正在执行的 SQL 语句,因此您不必将值集中到字符串中然后执行。

yes, by using sp_executesql:

DECLARE @nSQL NVARCHAR(500)
DECLARE @NewID INTEGER

SET @nSQL = 'INSERT MyTable (MyField) VALUES (123) SELECT @NewID = SCOPE_IDENTITY()'
EXECUTE sp_executesql @nSQL, N'@NewID INTEGER OUTPUT', @NewId OUTPUT

--@NewId now contains the ID

The advantage of sp_executesql is you can parameterise the SQL statement being executed, so you don't have to concentenate values into a string to then be executed.

土豪我们做朋友吧 2024-08-29 08:25:04

我遇到了同样的问题,但我没有使用 sp_executesql,而是使用了更原生的解决方案,该解决方案也适用于您想要带入外部的其他数据。

您可以将变量从 EXEC 内部传递到调用范围,如下所示:

DECLARE @Result AS Table (Value int)
INSERT INTO @Result EXEC('INSERT INTO MyTable(Fields) ''Value''; SELECT @@IDENTITY')
SELECT Value FROM @Result

I had the same problem, but instead of using sp_executesql I've used a more native solution which also works for other data you want to bring outside.

You can pass variables from inside the EXEC to the calling scope like this:

DECLARE @Result AS Table (Value int)
INSERT INTO @Result EXEC('INSERT INTO MyTable(Fields) ''Value''; SELECT @@IDENTITY')
SELECT Value FROM @Result
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文