作为存储过程的一部分,将多行插入到表中(不需要)

时间:2018-12-07 10:14:09

标签: sql sql-server stored-procedures concurrency

更新:这仍然是一个谜。检查了调用代码,我们没有发现任何会使SP循环运行的内容。 目前,我们已将SP分为两部分,尽管无法说明如何解决问题,但似乎已解决了该问题。

数据库:MS SQL Server。

我有一个执行少量操作的SP-即根据某些状态将行插入3个表中,作为该SP的一部分被调用。

它是根据用户操作从我们的Web应用程序中调用的。

在某些情况下,一天几次会多次插入同一行(有时超过50次以上),并且每行中的值都相同,但如果您查看插入行的日期时间会有所不同几毫秒。因此,用户不太可能启动该操作。

此SP不在事务中运行或未带有任何锁,但是由于我们在Web应用程序上有许多并发用户正在调用此操作,因此它可能被并发多次调用。

我的问题是什么导致同一行多次插入?如果SP的并发执行是我们要更新同一行的问题,那么可以理解一个人可能会覆盖另一个人。但是,在这种情况下,每个用户使用不同的参数调用SP。

我已将上述操作放在事务中以监视行为,但是希望找出是什么原因导致这种具有相同值的多次插入仅相隔数毫秒而已?

  USE [ABC]
GO
/****** Object:  StoredProcedure [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog] 
(
--Insert using bulk
@stdfrm_id int,
@course_id int,
@stdfrm_scrt_apprvby int,
@stdfrm_scrt_apprvcomment varchar(max),
@sRemainingDocs varchar(max),
@DTProcessAdmittedDocUploadScrutiny AS dbo.MyDTProcessAdmittedDocUploadScrutiny READONLY
)
AS
BEGIN   

DECLARE @result char
SET @result='N'

--New
declare @AuditCount int=0;
select @AuditCount=count(scrtaudit_id) from tbl_ProcessAdmittedScrutinyAuditLog 
where stdfrm_id=@stdfrm_id and stdfrm_scrt_apprvby=@stdfrm_scrt_apprvby 
and stdfrm_scrt_apprvcomment=@stdfrm_scrt_apprvcomment and convert(date,stdfrm_scrt_apprvon,103)=convert(date,getdate(),103)
 --Checked extra conditon to avoid repeatation
 if(@AuditCount=0)
 BEGIN
 --Call Insert


BEGIN TRY


/*Remaining Documents----------*/
    DECLARE @sdtdoc_id Table (n int primary key identity(1,1), id int) 
    if(@sRemainingDocs is not null)
    begin
    --INSERT INTO @sdtdoc_id (id)   SELECT Name from splitstring(@sRemainingDocs)
    INSERT INTO @sdtdoc_id (id) SELECT [Value] from dbo.FN_ListToTable(@sRemainingDocs,',')
    end
    Declare @isRemaining int=0;
    SELECT @isRemaining=Count(*) FROM @sdtdoc_id

/*Calculate stdfrm_scrt_apprvstatus*/
Declare @stdfrm_scrt_apprvstatus char(1)='A';--Approved
Declare @TotalDescripancies int;
select @TotalDescripancies=count(doc_id) from @DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y'
if(@isRemaining>0)
begin
    set @stdfrm_scrt_apprvstatus='H';--Discrepancies Found
end
else if exists (select count(doc_id) from @DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y')
begin
    if(@TotalDescripancies>0)
    begin
        set @stdfrm_scrt_apprvstatus='H';--Discrepancies Found
    end     
end
/* Check if Discrepancies Found first time then assign to Checker o.w assign to direct college  like grievance*/
if(@stdfrm_scrt_apprvstatus='H')
begin
declare @countAuditLog int=0;
select @countAuditLog=count(stdfrm_id) from tbl_ProcessAdmittedScrutinyAuditLog where stdfrm_id =@stdfrm_id
if (@countAuditLog=0)
begin
 set @stdfrm_scrt_apprvstatus='G'--'E';--Discrepancies Found set Edit request assign to Checker 
end
--else if (@countAuditLog=1)
-- begin
--set @stdfrm_scrt_apprvstatus='G';--Discrepancies Found set Grievance assign to college
-- end
end
/*----------------------*/

/*Update status in original table-----*/
Update tbl_ProcessAdmitted set stdfrm_scrt_apprvstatus=@stdfrm_scrt_apprvstatus
,stdfrm_scrt_apprvon=getdate(),stdfrm_scrt_apprvby=@stdfrm_scrt_apprvby
,stdfrm_scrt_apprvcomment=@stdfrm_scrt_apprvcomment
where stdfrm_id =@stdfrm_id

/*Add in Main Student Log-----------*/
/********* The row here gets inserted multiple times *******************/
INSERT into tbl_ProcessAdmittedScrutinyAuditLog
(stdfrm_id, stdfrm_scrt_apprvstatus, stdfrm_scrt_apprvon, stdfrm_scrt_apprvby, stdfrm_scrt_apprvcomment )
values
(@stdfrm_id, @stdfrm_scrt_apprvstatus, getdate(), @stdfrm_scrt_apprvby, @stdfrm_scrt_apprvcomment)

DECLARE @scrtaudit_id int =@@identity
/*Completed -------------------------*/

DELETE FROM tbl_ProcessAdmittedDocUploadScrutiny WHERE stdfrm_id =@stdfrm_id
SET NOCOUNT ON;

/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutiny
(stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment) 
SELECT @stdfrm_id, @course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM @DTProcessAdmittedDocUploadScrutiny;

/*Scrutiny Document Log -------------------------*/

/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutinyAuditLog
(scrtaudit_id,stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment) 
SELECT @scrtaudit_id,@stdfrm_id, @course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM @DTProcessAdmittedDocUploadScrutiny;

/*Remaining Documents Insert into table*/

DELETE FROM tbl_ProcessAdmittedDocUploadScrutinyRemiaing WHERE stdfrm_id =@stdfrm_id

        DECLARE @Id int,@doc_id int
        WHILE (SELECT Count(*) FROM @sdtdoc_id) > 0
            BEGIN
                Select Top 1 @Id = n,@doc_id=id From @sdtdoc_id                 
                --Do some processing here

                insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaing(stdfrm_id, doc_id ) 
                values (@stdfrm_id,@doc_id)

                insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaingAuditLog
                (scrtaudit_id, stdfrm_id, doc_id ) 
                values (@scrtaudit_id,@stdfrm_id,@doc_id)

                DELETE FROM @sdtdoc_id WHERE n = @Id

            END --Begin end While
/*End Remaining Documents-----------*/

SET @result=@stdfrm_scrt_apprvstatus    

END TRY
BEGIN CATCH
SET @result='N'


insert into tbl_ErrorSql( ErrorMessage,  stdfrm_id)
values(coalesce(Error_Message(),ERROR_LINE()),@stdfrm_id)
END CATCH;

--End of Call Insert
END

SELECT @result

END

0 个答案:

没有答案