3 votes

SQL : Est-il possible d'utiliser Order By dans une instruction de mise à jour ?

Je dois mettre à jour un seul enregistrement dans une base de données et l'attribuer à un utilisateur. Voici ce que je fais :

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

J'ai également un champ nommé bookname que je préférerais classer par ordre, mais update ne semble pas le prendre en charge.

Notez également que j'aurai 50 utilisateurs qui utiliseront le logiciel en même temps, et que je devrai donc m'assurer qu'un seul utilisateur se voit attribuer un livre. Dans le cas contraire, je lancerais d'abord une sélection, puis une mise à jour sur l'enregistrement le plus important.

T

2voto

Adrian Carneiro Points 26652

Vous devez d'abord sélectionner l'enregistrement souhaité, puis le mettre à jour :

update books
    set assigneduser = 1
where BookPrimaryKeyField = (
    SELETE TOP 1 BookPrimaryKeyField
    from books
    WHERE bookstatus = 7
    AND ((assigneduser is null) or (assigneduser = 1));
)

1voto

Otávio Décio Points 44200

Si vous souhaitez mettre à jour une seule ligne de la base de données, la meilleure façon de le faire est de trouver sa clé primaire et de l'utiliser. Vous pouvez le faire en disant

UPDATE books SET assigneduser = 1
WHERE BOOKID 
= (SELECT top 1 BOOKID FROM books where
 bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1)));

0voto

faester Points 6055

Étant donné que la mise à jour ne renvoie aucune donnée et que l'ordre par trie un ensemble de résultats, il n'y a rien pour ORDER BY à travailler, et ce que vous cherchez ne peut pas être fait.

Si vous souhaitez n'attribuer qu'un seul livre, vous pouvez le mettre à jour à l'aide d'une jointure sur le premier livre de votre ensemble.

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

ou peut-être moins cryptique

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

La robustesse de cette stratégie en matière de concurrence dépend de la sémantique des transactions.

0voto

The Evil Greebo Points 3491
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)

J'ai supposé que vous aviez une colonne d'identification bookid.

Cela vous permet d'obtenir l'identifiant de livre le plus bas, sans utilisateur assigné, et de le relier aux livres pour obtenir un enregistrement unique (en tant que partie de b) que vous pouvez ensuite mettre à jour.

0voto

Petar Ivanov Points 29530

Regarder http://msdn.microsoft.com/en-us/library/ms177523.aspx .

Si vous devez utiliser TOP pour appliquer des mises à jour dans une chronologie significative, vous devez utiliser TOP avec ORDER BY dans une instruction de sous-sélection. L'exemple suivant met à jour les heures de vacances des 10 salariés dont la date d'embauche est la plus ancienne.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X