当前位置:  开发笔记 > 数据库 > 正文

SQL更新top1行查询

如何解决《SQL更新top1行查询》经验,为你挑选了3个好方法。

以下查询正在运行:

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.AccountIdSET和之间WHERE)



1> Remus Rusanu..:
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锁.
@ErikE:*我可能会不必要地警告*如果您认为发生的情况(使用S锁或甚至nolock进行扫描,然后更新)将会发生警告将非常有必要.如果感兴趣的行将在连接或子查询中获取,那么你提到的问题*会发生,并且锁定提示是必要的.但由于更新直接针对CTE,因此引擎知道它必须做什么.
@RemusRusanu我不确定是否会更改任何内容。查询会随着时间的推移而执行,并具有锁获取生命周期,当所选的行依赖于其他行的数据时(如ORDER BY一样),会出现并发问题。其他行的读取发生在更新锁之前,因此并发是一个问题。如果此特定查询由两个客户端同时执行,则不会有有害的副作用,因此我可能不必要地发出警告-我只是看到了该查询模式重用的潜在问题,并予以注意。

2> storm_buster..:

你为什么不这样做:

update ShipBillInfo 
set shipfirstname='kkk' 
where OrderGUID = (select top (1) OrderGUID  
                   from ShipBillInfo 
                   where CustomerId = 134 
                   order by OredrGUID desc )



3> fabricioriss..:
线程安全

对于线程安全解决方案,所提出的解决方案都不适用于我(某些行在同时执行时不止一次更新).

这有效:

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.AccountIdSET和之间WHERE)

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有