SQL 服务器:获取 SCOPE_IDENTITY() 无法与链接服务器一起工作
SQL Server: getting SCOPE_IDENTITY() not working with linked server
我有一个存储过程,我在其中执行插入操作并通过调用 SCOPE_IDENTITY()
检索行的 ID
...
INSERT INTO [RemoteDB].[dbo].[Table] (StageID, UserID, Date)
VALUES (4, @userID, @date)
SET @id = SCOPE_IDENTITY()
INSERT INTO [RemoteDB].[dbo].[Table2] (ID)
VALUES (@id)
...
当我的 3 个数据库在同一台服务器上时一切正常,但在生产中,其中一个数据库是远程的(所以我使用链接服务器)。
我的查询的第一个插入有效,但第二个无效 运行。我认为这是因为 SCOPE_IDENTITY()
。
我的错误是:
The OLE DB provider could not INSERT INTO... "The value violated the integrity constraints for the column.".
这意味着它无法获取 SCOPE_IDENTITY()
的 @id
请注意,我执行的存储过程不在远程服务器上,它们在本地服务器上。
我做错了什么?
SCOPE_IDENTITY
(和类似的)不会像您对链接服务器的想法那样工作。来自 MSDN docs:
Returns the last identity value inserted into an identity column in
the same scope. A scope is a module: a stored procedure, trigger,
function, or batch. Therefore, if two statements are in the same
stored procedure, function, or batch, they are in the same scope.
由于您的插入发生在远程服务器上,而您的 SCOPE_IDENTITY
调用发生在本地,因此它们在不同的范围内执行。因此,您的 SCOPE_IDENTITY
调用可能是 returning NULL,因此违反了约束条件。
您有几个选项可以解决这个问题。第一种方法是只在远程服务器上编写一个存储过程,您可以执行它 a) 处理一个过程中的所有插入或 b) 处理单个插入并 return 您插入的身份。 (或者,您可以使用动态-sql-esque 解决方案在远程服务器上执行与建议的存储过程相同的语句。)无论您选择做什么,最终目标都是您必须确保 SCOPE_IDENTITY
调用在同一批次的远程服务器上发生,否则将无法工作。
请看下面的附图。就我而言,这就是我所做的。
在远程服务器上:
ALTER PROC [dbo].[SaveCustomerDetails]
(
@customerId int out,
@customerName varchar(100),
@contactNo varchar(100),
@custType varchar(1),
@idNo varchar(10)
)
在我的本地服务器上:
DECLARE @customerId INT
EXEC RCMS.[dbo].[SaveCustomerDetails] @customerId out, 'TEST ACCOUNT', '', 'O', '1511'
SELECT @customerId as id
具体来说,请注意
中的 'out' 关键字
@customerId out
我有一个存储过程,我在其中执行插入操作并通过调用 SCOPE_IDENTITY()
...
INSERT INTO [RemoteDB].[dbo].[Table] (StageID, UserID, Date)
VALUES (4, @userID, @date)
SET @id = SCOPE_IDENTITY()
INSERT INTO [RemoteDB].[dbo].[Table2] (ID)
VALUES (@id)
...
当我的 3 个数据库在同一台服务器上时一切正常,但在生产中,其中一个数据库是远程的(所以我使用链接服务器)。
我的查询的第一个插入有效,但第二个无效 运行。我认为这是因为 SCOPE_IDENTITY()
。
我的错误是:
The OLE DB provider could not INSERT INTO... "The value violated the integrity constraints for the column.".
这意味着它无法获取 SCOPE_IDENTITY()
@id
请注意,我执行的存储过程不在远程服务器上,它们在本地服务器上。
我做错了什么?
SCOPE_IDENTITY
(和类似的)不会像您对链接服务器的想法那样工作。来自 MSDN docs:
Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, if two statements are in the same stored procedure, function, or batch, they are in the same scope.
由于您的插入发生在远程服务器上,而您的 SCOPE_IDENTITY
调用发生在本地,因此它们在不同的范围内执行。因此,您的 SCOPE_IDENTITY
调用可能是 returning NULL,因此违反了约束条件。
您有几个选项可以解决这个问题。第一种方法是只在远程服务器上编写一个存储过程,您可以执行它 a) 处理一个过程中的所有插入或 b) 处理单个插入并 return 您插入的身份。 (或者,您可以使用动态-sql-esque 解决方案在远程服务器上执行与建议的存储过程相同的语句。)无论您选择做什么,最终目标都是您必须确保 SCOPE_IDENTITY
调用在同一批次的远程服务器上发生,否则将无法工作。
请看下面的附图。就我而言,这就是我所做的。
在远程服务器上:
ALTER PROC [dbo].[SaveCustomerDetails]
(
@customerId int out,
@customerName varchar(100),
@contactNo varchar(100),
@custType varchar(1),
@idNo varchar(10)
)
在我的本地服务器上:
DECLARE @customerId INT
EXEC RCMS.[dbo].[SaveCustomerDetails] @customerId out, 'TEST ACCOUNT', '', 'O', '1511'
SELECT @customerId as id
具体来说,请注意
中的 'out' 关键字@customerId out