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等),我也测试了隐式转换问题.
这个问题只发生一次,即使使用备份也无法复制,但我担心如果我找不到原因,它可能会再次发生.
我不明白你到底想做什么。我根据我的理解给你一个方法。您可以检查该条目是否已更新,如果已更新,则将其插入到 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)
归档时间: |
|
查看次数: |
187 次 |
最近记录: |