Sql server 在SQL Server中同时从2条insert语句返回作用域标识

Sql server 在SQL Server中同时从2条insert语句返回作用域标识,sql-server,stored-procedures,Sql Server,Stored Procedures,我的存储过程有问题: CREATE PROCEDURE [dbo].[Project] @Code as nvarChar(255) = null, @Id as nvarChar(255) = null, @Status as nvarChar(max) = null, @Project as nvarChar(max) = null, @ClientSystem as nvarchar(max) = null, @UserId as bigi

我的存储过程有问题:

CREATE PROCEDURE [dbo].[Project] 
    @Code as nvarChar(255) = null,
    @Id as nvarChar(255) = null,
    @Status as nvarChar(max) = null,
    @Project as nvarChar(max) = null,
    @ClientSystem as nvarchar(max) = null,
    @UserId as bigint = 0,
    @ProjectId as bigint = 0,
    @ProjectDetailsId bigint = 0 Output
AS
    SET NOCOUNT OFF;

    IF NOT EXISTS (SELECT [Code]
                   FROM [dbo].[Project]
                   WHERE Project.Code = @Code)
    BEGIN
        INSERT INTO [dbo].[Project]([Code], [Id], [Status], [Project])
        VALUES(@Code, @Id, @Status, @Project)

        SELECT @ProjectId = SCOPE_IDENTITY()

        INSERT INTO [dbo].[ProjectDetails]([FK_ProjectId], [ClientSystem], [UserId])
        VALUES(@ProjectId, @ClientSystem, @UserId)

        SELECT @ProjectDetailsId = SCOPE_IDENTITY()
     END
     ELSE
     BEGIN
        SELECT [ProjectId] AS 'ProjectId'
        FROM [dbo].[Project]
        WHERE Project.Code = @Code
     END
我想从两个
Insert
语句返回
Scope\u Identity
,并将第一个Insert的值作为参数传递给第二个Insert,同时返回第二个Insert语句的
Scope\u Identity


我得到的错误是,当我获得第一个
插入的标识时,特定表中的标识将增加2倍,就像在db表中一样,它将被插入2,但在编码中它将返回1。当我传递到另一个insert时,它返回的是冲突。

解决方案:您需要使用
insert
语句的
输出
子句,而不是使用
范围标识()

INSERT INTO [dbo].[Project]([Code], [Id], [Status], [Project])
OUTPUT inserted.ID into @ProjectID
SELECT ...
说明:
SCOPE\u IDENTITY()
返回最后一次插入的值,无论插入发生在何处。因此,当另一个
insert
并行运行时,调用
SCOPE\u IDENTITY()
将返回其他并行运行过程中的值。这将导致一个错误

但是,使用
输出
子句将保证从当前的
插入
返回值

下面是一篇关于
范围_标识
和并行计划的有趣文章:
您需要在过程参数处使用OUTPUT子句

@ProjectId as bigint = 0 output,

在我看来,你的代码可以插入,除了你的
@ProjectId为bigint=0,
不是
output
参数非常好的问题,upvote@ughai不,这不是原因。原因是
SCOPE\u IDENTITY()
返回最后一次插入的值,而不管它发生在哪里。因此,当第二个insert并行运行时,对
SCOPE\u IDENTITY()
的调用将从另一个并行运行过程返回值。@ughai否。这是一个已知的问题。唯一正确的方法是
输出
子句。Microsoft声明:@SQLPolice-它与查询本身的并行执行计划有关,与“第二次插入正在并行运行”无关。不,这不是原因。原因是
SCOPE\u IDENTITY()
返回最后一次插入的值,而不管它发生在哪里。因此,当第二个insert并行运行时,调用
SCOPE\u IDENTITY()
将返回另一个并行运行过程的值。@SeanLange您错了。就连皮纳尔·戴夫两年后也改过自新了。嗯,很有趣。6年了,不知怎的,我错过了这一次。我将接受更正,并将删除我以前的错误陈述。我会撤回我的否决票,但除非答案被编辑,否则我不能撤回。@SeanLange OK!如果你也取消了否决票,那就太好了;)我记得我自己也不在乎这个问题,一些触发器产生了错误。但我现在不知道细节。我会撤回我的反对票,但除非答案被编辑,否则我不能。考虑到我以前犯的严重错误,我不想为此进行编辑。如果您编辑它,我将删除它:D