2013-10-25 15 views
17

Ho un seguente query:SQL UPDATE TOP con ORDINARE BY?

UPDATE TOP (@MaxRecords) Messages 
SET status = 'P' 
OUTPUT inserted.* 
FROM Messages 
where Status = 'N' 
and InsertDate >= GETDATE() 

Nella tabella Messaggi c'è colonna di priorità e voglio seleci messaggi ad alta priorità prima. Quindi ho bisogno di un ordine. Ma non ho bisogno di avere l'output ordinato ma i dati ordinati prima dell'esecuzione dell'aggiornamento.

Per quanto ne so non è possibile aggiungere ORDER BY all'istruzione UPDATE. Altre idee?

m.

+1

Possibile duplicato di [query di aggiornamento superiore1 riga SQL] (http://stackoverflow.com/questions/3860975/sql-update-top1-row-query) – fabriciorissetto

+0

Possibile duplicato di [Come aggiornare e ordinare utilizzando ms sql ] (http://stackoverflow.com/questions/655010/how-to-update-and-order-by-using-ms-sql) – Athafoud

risposta

27

è possibile utilizzare un'espressione di tabella comuni per questo:

;with cte as (
    select top (@MaxRecords) 
     status 
    from Messages 
    where Status = 'N' and InsertDate >= getdate() 
    order by ... 
) 
update cte set 
    status = 'P' 
output inserted.* 

Questo si usa il fatto che in SQL Server è possibile aggiornare cte, come la vista aggiornabile.

-6

la sintassi corretta di aggiornamento è

UPDATE [LOW_PRIORITY] [IGNORE] table_reference 
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... 
[WHERE where_condition] 
[ORDER BY ...] 
[LIMIT row_count] 
+0

Non in Sql Server. – mark

12

si può provare sub domanda come

UPDATE Messages 
    SET status = 'P' 
    WHERE MessageId IN (SELECT TOP (@MaxRecords) MessageId FROM Messages where Status = 'N' and InsertDate >= GETDATE() ORDER BY Priority) 
output inserted.* 
+0

Nel mio caso non stavo usando TOP perché volevo aggiornare tutti i record corrispondenti dalla clausola WHERE e ho ricevuto l'errore: "La clausola ORDER BY non è valida nelle viste, funzioni inline, tabelle derivate, sottoquery e espressioni di tabella comuni , a meno che sia specificato anche TOP, OFFSET o FOR XML. " Aggiungendo un manichino TOP (100000) fallo funzionare. Non so se ci sia una soluzione migliore nel mio caso. –

+2

@AugustoBarreto puoi usare 'top 100 percento' per prendere tutti i record invece di un numero fittizio. – Athafoud

+0

Grazie! Non lo sapevo. Leggendo i documenti: "Limita le righe restituite in un risultato di query impostato su un numero specificato di righe o percentuale di righe" –