循环可以锁定吗?

jea*_*ean 5 sql t-sql sql-server

循环可以锁定吗?

昨晚,测试团队打开了一个奇怪的嘀嗒声.该应用程序有一个网格,用户可以检查事件是否推迟测试人员选择了两个事件(ID:1和5),推迟了两个,但一个没有更新状态

我知道必须更新[Incident]表并在[IncidentDetail]表中插入一条新记录我同时查询并喜欢这个:

Id IncidentKindCode TransportEntryId CreateDate             IncidentStatus CloseDate
-- ---------------- ---------------- ---------------------- -------------- ---------
1  11301            52               2014-08-26 19:23:21.47 1              NULL
5  11301            56               2014-08-26 20:06:17.94 0              NULL

Id IncidentId  InsertDate             DetailKind Reason    IncidentUser PostponeDate
-- ----------- ---------------------- ---------- --------- ------------ -----------------------
9  1           2014-08-26 20:28:37.37 1          TEST TEST 8            2014-08-27 00:00:00.000
10 5           2014-08-26 20:28:37.37 1          TEST TEST 8            2014-08-27 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

测试者抱怨是有效的,因为[Incident].[IncidentStatus]值此时必须为零.在深入挖掘之后,我捕获了应用程序发送到服务器的确切查询(感谢分析器).

declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,N'@IDINCIDENT varchar(max) ,@REASON varchar(max) ,@USERCODE varchar(max) ,@POSTPONEDATE varchar(max) ',N'
DECLARE @ARRAY VARCHAR(8000), @DELIMITADOR VARCHAR(100), @SELECTEDID VARCHAR(8000);

SELECT @ARRAY = @IDINCIDENT
SELECT @DELIMITADOR = '';''

IF LEN(@ARRAY) > 0 SET @ARRAY = @ARRAY + @DELIMITADOR

WHILE LEN(@ARRAY) > 0
BEGIN

    SELECT @SELECTEDID = LTRIM(SUBSTRING(@ARRAY, 1,
    CHARINDEX(@DELIMITADOR, @ARRAY) - 1))

    BEGIN
        UPDATE [dbo].Incident SET INCIDENTSTATUS = 1 WHERE ID = @SELECTEDID
        INSERT [dbo].IncidentDetail (INCIDENTID, DETAILKIND, REASON, INCIDENTUSER, POSTPONEDATE)
                       VALUES (@SELECTEDID, 1, @REASON, @USERCODE, @POSTPONEDATE);
    END

    SELECT @ARRAY = SUBSTRING(@ARRAY,
    CHARINDEX(@DELIMITADOR, @ARRAY) + 1, LEN(@ARRAY))
END
',@IDINCIDENT='1;5',@REASON='querty',@USERCODE='1',@POSTPONEDATE='2014-08-28 00:00:00'
select @p1
Run Code Online (Sandbox Code Playgroud)

没有触发器,没有其他更新没有挂起的事务.据我所知,即使第一次循环迭代阻止第二次迭代到更新失败的点,也必须引发异常并回滚所有事务.

在插入工作时,更新可能会失败,这似乎是不合逻辑的.所有列都有标准类型(Int,Varchar(100),DateTime等),我也测试了隐式转换问题.

这个问题只发生一次,即使使用备份也无法复制,但我担心如果我找不到原因,它可能会再次发生.

Mih*_*hah 3

我不明白你到底想做什么。我根据我的理解给你一个方法。您可以检查该条目是否已更新,如果已更新,则将其插入到 IncidentDetail 中。

UPDATE [dbo].Incident SET INCIDENTSTATUS = 1 WHERE ID = @SELECTEDID

If Exists(  Select  1
            From    [dbo].Incident As I
            Where   I.ID = @SELECTEDID
                    And I.INCIDENTSTATUS = 1
         )
Begin
    INSERT [dbo].IncidentDetail (INCIDENTID, DETAILKIND, REASON, INCIDENTUSER, POSTPONEDATE)
                       VALUES (@SELECTEDID, 1, @REASON, @USERCODE, @POSTPONEDATE);
End
Run Code Online (Sandbox Code Playgroud)