2010-10-05 5 views
25

Запрос ниже работает:SQL обновление top1 строки запроса

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; 
+0

Некоторые больше информации будет хороший? Настольная информация? Пример данных? – Tim

ответ

21

почему бы вам не сделать:

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

Имейте в виду, что это не обрабатывает параллелизм, поэтому при одновременных вызовах он может обновлять одну и ту же строку дважды. – fabriciorissetto

25
With cte as (
select top(1) shipfirtsname 
From ShipBillInfo 
where CustomerId='134' 
order by OredrGUID desc) 
Update cte set shipfirstname='abc'; 
+0

Это работает лучше при подключении таблиц. –

+1

Будьте осторожны с параллелизмом на этом ... – ErikE

+0

@ErikE Вы имели в виду множественность (1: многие отношения в таблице), или вы действительно имели в виду параллелизм (более одного пользователя/соединения, меняющих одну и ту же строку одновременно)? – yzorg

6

Thread Safe

Для решения потокобезопасного решения ни один из предложенных решений не работал для меня (несколько строк обновлялись более одного раза при одновременном выполнении).

Это сработало:

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)

Смежные вопросы