VB.Net获取要在事务中使用的scope_identity()

时间:2014-08-05 15:22:57

标签: sql sql-server vb.net

我正在使用VB.Net事务来执行两个查询。有两张桌子和一张桌子。以下是一个示例结构。

USER
----
1. USER_ID - int (PK) AUTO_INCREMENT
2. USER_NAME - varchar(20)

ADDRESS
-----
1. USER_ID
2. USER_ADDRESS

由于这个基本结构代表一个用户可以拥有很多照片。每当我向USER表插入新记录时,应使用自动创建的USER_ID保存用户的照片。

我知道我需要为此目的使用SCOPE_IDENTITY(),但我总是为SCOPE_IDENTITY()值获取NULL,这不是因为触发器或其他任何原因。问题在于VB.Net如何创建我的INSERT语句。

以下是SQLServer Profiler中查询的外观

插入USER表

exec sp_executesql N'INSERT INTO USER(USER_NAME) VALUES (@USER_NAME)',N'@USER_NAME nvarchar(4)',@USER_NAME =N'ABCD'

插入地址表

exec sp_executesql N'INSERT INTO ADDRESS(USER_ID,USER_ADDRESS) VALUES ((SELECT SCOPE_IDENTITY()),@USER_ADDRESS)',N'@ USER_ADDRESS nvarchar(10)',@USER_ADDRESS=N'ABCDEFGHIJ'

我已将SELECT SCOPE_IDENTITY()直接附加到第二个查询&我认为SQL认为命令SCOPE_IDENTITY()是一个字符串,我该如何防止这种情况发生。

1 个答案:

答案 0 :(得分:4)

顾名思义,scope_identity()是范围的本地。 sp_executesqlits own scope内运行。稍后对sp_executesql的调用没有对早期范围的记忆。

最合乎逻辑的解决方案是在同一范围内运行两个查询。我不确定你使用sp_executesql的原因;也许你可以省略它。大多数客户运行如下:

INSERT INTO USER(USER_NAME) VALUES (@USER_NAME);
SELECT SCOPE_IDENTITY() AS ID;

客户端程序可以从生成的行集中获取ID。然后,它可以将ID作为参数传递给INSERT地址查询。不需要sp_executesql

如果您必须使用多个sp_executesql,请考虑使用output参数来传送身份:

declare @ID bigint

exec sp_executesql 
    N'INSERT INTO USER(USER_NAME) VALUES (@USER_NAME);
      SELECT @ID = SCOPE_IDENTITY();',
    N'@USER_NAME nvarchar(4), @ID bigint output',
    @USER_NAME = N'ABCD',
    @ID = @ID output;

现在,您可以将@ID作为变量传递给第二个sp_executesql