SQL: есть ли способ использовать Order By в операторе обновления? - PullRequest
3 голосов
/ 10 июня 2011

Мне нужно обновить только одну запись в базе данных и назначить ее пользователю. Вот что я делаю:

UPDATE TOP (1) books SET assigneduser = 1
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1));

У меня также есть поле с именем bookname, по которому я бы предпочел упорядочить, но обновление, похоже, не поддерживает его.

Также обратите внимание, что у меня будет 50 пользователей, использующих программное обеспечение одновременно, поэтому мне нужно убедиться, что только одному пользователю назначена книга. В противном случае я сначала запустил бы выбор, а затем обновление в верхней записи.

Спасибо.

Ответы [ 7 ]

2 голосов
/ 10 июня 2011

Вы должны сначала выбрать нужную запись, а затем обновить ее:

update books
    set assigneduser = 1
where BookPrimaryKeyField = (
    SELETE TOP 1 BookPrimaryKeyField
    from books
    WHERE bookstatus = 7
    AND ((assigneduser is null) or (assigneduser = 1));
)
1 голос
/ 10 июня 2011

Если вы хотите обновить только одну строку в базе данных, лучший способ сделать это - выяснить, каков ее первичный ключ, и использовать его. Вы можете сделать это, сказав

UPDATE books SET assigneduser = 1
WHERE BOOKID 
= (SELECT top 1 BOOKID FROM books where
 bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1)));
0 голосов
/ 10 июня 2011

Есть способ обойти это, используя подзапрос следующим образом:

UPDATE books SET assigneduser=1
AND ((assigneduser is null) or (assigneduser = 1))
AND bookname in (SELECT TOP 1 bookname FROM Table ORDER BY bookname DESC) 
0 голосов
/ 10 июня 2011

Вероятно, было бы легче разбить это на 2 части

    DECLARE @bookid as INT

    SELECT TOP (1) @bookid = id FROM books
    WHERE bookstatus = 7
    AND ((assigneduser is null) or (assigneduser = 1))
    ORDER BY bookname

    UPDATE books SET assigneduser = 1
    WHERE id = @bookid
0 голосов
/ 10 июня 2011

Посмотрите на http://msdn.microsoft.com/en-us/library/ms177523.aspx.

Если вам необходимо использовать TOP для применения обновлений в содержательной хронологии, вы должны использовать TOP вместе с ORDER BY в операторе подвыбора. В следующем примере обновляются часы отпуска 10 сотрудников с самыми ранними датами приема на работу.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO
0 голосов
/ 10 июня 2011
UPDATE B
SET assigneduser = 1
FROM books B
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1))
and bookid = (select min(bookid) from books where assigneuser is null)

Я предполагал, что у вас есть идентификатор столбца bookid.

Это дает вам самый низкий идентификатор книги без назначенного пользователя и присоединяет его обратно к книгам, чтобы дать вам одну запись (как часть b), которую вы затем можете обновить.

0 голосов
/ 10 июня 2011

Поскольку обновление не возвращает никаких данных, а 'order by' сортирует набор результатов, ORDER BY не с чем работать, и то, что вы ищете, не может быть сделано.

Если вы хотитеназначьте только одну книгу, которую вы можете обновить, используя объединение сверху 1 из вашего набора.

UPDATE b0 SET assigneduser = 1
FROM b0 
  INNER JOIN
(SELECT top 1 id FROM books
WHERE user = 1 OR user is null
AND status =7)  b1 ON b1.id = b0.id

или, возможно, менее загадочный

UPDATE user SET assigneduser = 1
WHERE id IN
(SELECT top 1 id FROM books
WHERE user = 1 OR user is null
AND status =7)  b1 ON b1.id = b0.id

Является ли эта стратегия устойчивой в отношении параллелизма, зависитсемантика транзакций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...