以下查询正在运行:
update top(1) ShipBillInfo set shipfirstname='kkk' where CustomerId='134';
但如果我尝试按某些Id订购,则显示错误:例如:
update top(1) ShipBillInfo set shipfirstname='kkk' where CustomerId='134' order by OredrGUID desc;
Remus Rusanu.. 32
With cte as ( select top(1) shipfirtsname From ShipBillInfo where CustomerId='134' order by OredrGUID desc) Update cte set shipfirstname='abc';
@ErikE:*在更新锁定之前发生其他行的读取*:否.阅读本身是否采取U锁定.这就是我所说的'CTE是UPDATE的目标'.扫描(或搜索)将获得U锁. (3认同)
@ErikE:*我可能会不必要地警告*如果您认为发生的情况(使用S锁或甚至nolock进行扫描,然后更新)将会发生警告将非常有必要.如果感兴趣的行将在连接或子查询中获取,那么你提到的问题*会发生,并且锁定提示是必要的.但由于更新直接针对CTE,因此引擎知道它必须做什么. (3认同)
@RemusRusanu我不确定是否会更改任何内容。查询会随着时间的推移而执行,并具有锁获取生命周期,当所选的行依赖于其他行的数据时(如ORDER BY一样),会出现并发问题。其他行的读取发生在更新锁之前,因此并发是一个问题。如果此特定查询由两个客户端同时执行,则不会有有害的副作用,因此我可能不必要地发出警告-我只是看到了该查询模式重用的潜在问题,并予以注意。 (2认同)
storm_buster.. 22
你为什么不这样做:
update ShipBillInfo set shipfirstname='kkk' where OrderGUID = (select top (1) OrderGUID from ShipBillInfo where CustomerId = 134 order by OredrGUID desc )
fabricioriss.. 7
线程安全
对于线程安全解决方案,所提出的解决方案都不适用于我(某些行在同时执行时不止一次更新).
这有效:
UPDATE Account SET sg_status = 'A' WHERE AccountId = ( SELECT TOP 1 AccountId FROM Account WITH (UPDLOCK) --this makes it thread safe ORDER BY CreationDate )
如果要返回更新项的某些列,可以将其放在更新语句中:( OUTPUT INSERTED.AccountId
在SET
和之间WHERE
)
With cte as ( select top(1) shipfirtsname From ShipBillInfo where CustomerId='134' order by OredrGUID desc) Update cte set shipfirstname='abc';
你为什么不这样做:
update ShipBillInfo set shipfirstname='kkk' where OrderGUID = (select top (1) OrderGUID from ShipBillInfo where CustomerId = 134 order by OredrGUID desc )
对于线程安全解决方案,所提出的解决方案都不适用于我(某些行在同时执行时不止一次更新).
这有效:
UPDATE Account SET sg_status = 'A' WHERE AccountId = ( SELECT TOP 1 AccountId FROM Account WITH (UPDLOCK) --this makes it thread safe ORDER BY CreationDate )
如果要返回更新项的某些列,可以将其放在更新语句中:( OUTPUT INSERTED.AccountId
在SET
和之间WHERE
)