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