SQL Server:使SCOPE_IDENTITY()无法使用链接服务器

时间:2017-12-27 13:56:28

标签: sql-server stored-procedures remote-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()

我的错误是:

  

OLE DB提供程序无法INSERT INTO ...“该值违反了列的完整性约束。”。

这意味着它无法获得@id

SCOPE_IDENTITY()

请注意,我执行的存储过程不在远程服务器上,而是在本地存储过程中。

我做错了什么?

enter image description here

2 个答案:

答案 0 :(得分:2)

SCOPE_IDENTITY(和类似的)不会像你想象的那样使用链接服务器。来自MSDN docs

  

返回插入标识列的最后一个标识值   相同的范围。范围是一个模块:存储过程,触发器,   功能或批处理。因此,如果两个陈述相同   存储过程,函数或批处理,它们属于同一范围。

由于您的插入是在远程服务器上进行的,而SCOPE_IDENTITY调用是在本地进行的,因此它们在不同的范围内执行。因此,您的SCOPE_IDENTITY调用可能返回NULL,因此违反约束。

您有几个选项可以解决此问题。第一种方法是在远程服务器上编写一个可以执行的存储过程,它可以a)处理一个proc中的所有插入,或者b)处理单个insert并返回插入的标识。 (或者,您可以使用dynamic-sql-esque解决方案在远程服务器上执行与建议的存储过程相同的语句。)无论您选择做什么,最终目标都是必须确保{{ 1}}调用在同一批次的远程服务器上发生,否则无效。

答案 1 :(得分:0)

请看下面的附图。就我而言,这就是我所做的。

在远程服务器上:

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

具体来说,请注意 in 中的 'out' 关键字

@customerId out