2010-02-19 36 views
3

我試圖找到由exec(@Sql)插入的插入記錄的標識值,但似乎exec()在不同的作用域中執行。如何在調用exec(@Sql)後獲取標識值

/* 
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()插入的身份值找到身份值?

回答

7

是,通過使用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 

[email protected] now contains the ID 

sp_executesql的的好處是你可以參數化正在執行的SQL語句,所以你不必值concentenate成一個字符串,然後被執行。

+0

那會做很好,謝謝。 – avenmore 2010-02-19 14:12:13

0

我有同樣的問題,但不是使用sp_executesql我已經使用了更原生的解決方案,它也適用於其他數據,你想帶外面。

您可以從EXEC內傳遞變量到這樣的呼叫範圍:

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