come posso aggiornare i primi 100 record nel server sql


393

Voglio aggiornare i primi 100 record in SQL Server. Ho un tavolo T1con campi F1e F2. T1ha 200 record. Voglio aggiornare il F1campo tra i primi 100 record. Come posso effettuare l'aggiornamento in base TOP 100a SQL Server?

Risposte:


684

Nota, le parentesi sono richieste per le istruzioni UPDATE:

update top (100) table1 set field1 = 1

28
Qualche idea su come usare order byanche questo?
Joe Phillips,

8
@JoePhilllips Usa la risposta di Martin Smith per ordinare entro
jjxtra l'

Questi non sono i primi 100 record, tuttavia, ma semplicemente 100 record scelti arbitrariamente. La top 100 includerebbe un certo ordine per classificare i record.
Thorsten Kettner,

1
Questo risponde alla domanda "come chiesto", ma TOP è insignificante (e imprevedibile) senza un ORDINE. Vedi la risposta più in basso di Martin Smith.
Andy G,

1
btw: le parentesi sono importanti!
Simon_Weaver

300

Senza ORDER BYl'idea di TOPnon ha molto senso. Devi avere una definizione coerente di quale direzione è "su" e quale "giù" perché il concetto di cima sia significativo.

Tuttavia SQL Server lo consente ma non garantisce un risultato deterministico .

La UPDATE TOPsintassi nella risposta accettata non supporta una ORDER BYclausola, ma è possibile ottenere qui una semantica deterministica utilizzando una tabella CTE o derivata per definire l'ordinamento desiderato come di seguito.

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'

71
Dici insignificante ma non è vero. Devo ammettere che, di solito /, quando stai usando le TOPprobabilità dovresti usarlo ORDER BYperché quello che ti interessa è come il "più" o il "meno" di qualcosa. In altri casi, tuttavia, potresti essere interessato a ottenere solo un record corrispondente. Come me oggi! Avevo bisogno di risolvere problemi di dati (cicli) uno alla volta. L'intero processo di correzione ha comportato uno script db, alcuni interventi dell'utente e alcune operazioni dell'applicazione. Non ci importava quale record è stato gestito per primo. Ci importava solo che li stessimo gestendo uno alla volta.
MetaFight

17
@MetaFight Ma allora avresti avuto una WHEREclausola per escludere i record elaborati in precedenza. La domanda come risposta scritta e accettata è piuttosto insignificante. A proposito: per usare le tabelle come coda questo è un collegamento abbastanza utile
Martin Smith,

10
Devo usare top senza ordine in modo da poter eseguire un processo asincrono. La clausola where non includerà quelle che sono già state elaborate, ma posso elaborarne solo tante alla volta. Quindi ha un caso d'uso perfettamente valido.
Jeff Davis,

4
@Martin Smith: diciamo che vuoi aggiornare in batch, diciamo 10000 alla volta. Sembra un buon uso per questo, e l'ordine non ha importanza. In che modo "non ha senso"?
Jay Sullivan,

5
@notfed Questo è lo stesso caso già discusso a morte nei commenti sopra. La tua domanda in quel caso non sembrerebbe quella della risposta accettata? Avresti bisogno di una whereclausola per evitare di elaborare ripetutamente le stesse righe.
Martin Smith,

14

per quelli come me ancora bloccati con SQL Server 2000, SET ROWCOUNT {number};possono essere utilizzati prima della UPDATEquery

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;

limiterà l'aggiornamento a 100 righe

È stato deprecato almeno da SQL 2005, ma a partire da SQL 2017 funziona ancora. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017


1
SET ROWCOUNT influisce sui trigger e sul comando da aggiornare. Se hai impostato l'eliminazione a cascata, la transazione può fallire se nella tabella figlio sono presenti più righe del numero di righe figlio.
EricI,

Detto questo, SET ROWCOUNT @RowCountParameter; è una sintassi valida, mentre SELECT TOP @RowCountParamter * FROM TableName non è valido. Se è necessario configurare le righe da aggiornare, SET ROWCOUNT # è attualmente l'opzione migliore, a condizione che non siano abilitate le tabelle figlio con l'eliminazione a cascata.
EricI,

In SQL Server 2017 è ora possibile utilizzare @variable nella clausola TOP: docs.microsoft.com/en-us/sql/t-sql/queries/…
Alexandr Zarubkin

13
update tb set  f1=1 where id in (select top 100 id from tb where f1=0)

4

Ciò che è ancora più interessante è il fatto che è possibile utilizzare una funzione con valori di tabella incorporata per selezionare quali (e quante TOPrighe) aggiornare. Questo è:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

Per la funzione con valori di tabella hai qualcosa di interessante per selezionare la riga da aggiornare come:

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

... e qui sta (a mio modesto parere) il vero potere di aggiornare deterministicamente solo le prime righe selezionate, semplificando allo stesso tempo la sintassi UPDATEdell'istruzione.


0

Provare:

UPDATE Dispatch_Post
SET isSync = 1
WHERE ChallanNo 
IN (SELECT TOP 1000 ChallanNo FROM dbo.Dispatch_Post ORDER BY 
CreatedDate DESC)

0

Puoi anche aggiornare da select usando l'alias e unirti:

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.