Domanda

Idealmente, voglio fare questo:

UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;

In inglese: desidero ottenere i primi 10 messaggi disponibili (stato = 0) dal DB e bloccarli (stato = 10). Un messaggio con una priorità più alta dovrebbe essere ricevuto per primo.

sfortunatamente MS SQL non consente un ordine per clausola nell'aggiornamento.

Comunque come aggirare questo?

È stato utile?

Soluzione

È possibile eseguire una sottoquery in cui si ottengono prima gli ID dei primi 10 ordinati per priorità e quindi si aggiornano quelli che si trovano su quella sotto query:

UPDATE  messages 
SET status=10 
WHERE ID in (SELECT TOP (10) Id 
             FROM Table 
             WHERE status=0 
             ORDER BY priority DESC);

Altri suggerimenti

WITH    q AS
        (
        SELECT  TOP 10 *
        FROM    messages
        WHERE   status = 0
        ORDER BY
                priority DESC
        )
UPDATE  q
SET     status = 10

Devo offrirlo come approccio migliore: non hai sempre il lusso di un campo di identità:

UPDATE m
SET [status]=10
FROM (
  Select TOP (10) *
  FROM messages
  WHERE [status]=0
  ORDER BY [priority] DESC
) m

Puoi anche rendere la query secondaria complicata quanto vuoi - unire più tabelle, ecc ...

Perché è meglio? Non si basa sulla presenza di un campo identità (o di qualsiasi altra colonna univoca) nella tabella messaggi . Può essere utilizzato per aggiornare le prime N righe da qualsiasi tabella, anche se quella tabella non ha alcuna chiave univoca.

UPDATE messages SET 
 status=10 
WHERE ID in (SELECT TOP (10) Id FROM Table WHERE status=0 ORDER BY priority DESC);

Come indicato nei commenti seguenti, è possibile utilizzare anche la clausola SET ROWCOUNT, ma solo per SQL Server 2014 e versioni precedenti.

SET ROWCOUNT 10

UPDATE messages
SET status = 10 
WHERE status = 0 

SET ROWCOUNT 0

Ulteriori informazioni: http://msdn.microsoft.com/en- us / library / ms188774.aspx

O con una tabella temporanea

DECLARE @t TABLE (id INT)
INSERT @t (id)
SELECT TOP 10 id
FROM messages
WHERE status = 0
ORDER BY priority DESC

UPDATE messages
SET status = 10
WHERE id IN (SELECT id FROM @t)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top