views:

239

answers:

6

I would like to update the top 400 rows in a database table. The pseudo SQL is below, how can I do this?

UPDATE top (400) db.dbo.tbl
SET column1 = 2
WHERE column2 = 1
  AND column1 is null
+2  A: 

How would you determine the top 400? With no order by there is no guanantee that the same set would always be selected and thus the wrong records could be updated.

HLGEM
+5  A: 
 update  db.dbo.tbl set column1 = 2 where
 primaryID in (
   SELECT top (400) primarkyID from db.dbo.tbl
   where column2 = 1 and column1 is null
 )

But I dont like this as there's no way to guarentee WHICH top 400, you might want to add some other type of criteria. And even an Order By to the subquery.

Neil N
+2  A: 

You're probably looking for something like this:

update db.dbo.tbl set column1 = 2 
where ID in (
  select top 400 ID from db.dbo.tbl
  where column2 = 1 and column1 is null --the criteria have been moved here
  order by ID --order by clause recommended
  )

where ID is the primary key column of the table.

Bernhof
You can also use `set rowcount 400` instead of using `TOP` in the query see http://msdn.microsoft.com/en-us/library/ms188774.aspx
pjp
Except that SET ROWCOUNT is deprecated.
Crappy Coding Guy
@Dave: Are you sure? I can't see that documented in the MSDN docs http://msdn.microsoft.com/en-us/library/ms188774.aspx
pjp
@pjp: If you scroll down a bit you'll find this text under Remarks:Important: Using SET ROWCOUNT will not affect DELETE, INSERT, and UPDATE statements in the next release of SQL Server. Do not use SET ROWCOUNT with DELETE, INSERT, and UPDATE statements in new development work, and plan to modify applications that currently use it. Also, for DELETE, INSERT, and UPDATE statements that currently use SET ROWCOUNT, we recommend that you rewrite them to use the TOP syntax. For more information, see DELETE (Transact-SQL), INSERT (Transact-SQL), or UPDATE (Transact-SQL).
Crappy Coding Guy
+4  A: 

If you're using SQL Server 2008, the "top n" syntax will work on delete and update statements. Otherwise, the other methods listed here where you identify the primary keys in a subquery or derived table will work well. And as others have done, the "order by" is highly recommended or the rows you update can differ from one query to the next.

Crappy Coding Guy
Also works on SQL 2005, but requires the brackets: TOP (n). See SQL 2005 BOL, UPDATE statement, TOP () clause.
Rick
+2  A: 
WITH    q AS
        (
        SELECT  TOP 400 *
        FROM    db.dbo.tb
        WHERE   column2 = 1
                AND column1 is null
        ORDER BY
                column3 -- choose your order!
        )
UPDATE  q
SET     column2 = 2
Quassnoi
@Quassnoi, just curious, what's the benefit of using a CTE instead of a subselect?
John M Gant
`@jmgant`: you cannot update a subselect like in `Oracle`, `UPDATE (SELECT TOP 400 * …) SET …` will fail. An `IN` condition proposed by others just results in an extra `JOIN` which is redundant here.
Quassnoi
Besides, this will work even if you don't have a `PRIMARY KEY` or have a composite `PRIMARY KEY` (in `SQL Server`, you cannot use more than one column in an `IN` predicate)
Quassnoi
He must be using SQL 2000, as SQL 2005 supports the TOP () clause for UPDATE statements. SQL 2000 doesn't have CTEs, so he can't really use this.
Rick
A: 

You can use following syntax

UPDATE top (400) tbl SET column1 = '2' WHERE column2 = '1' AND column1 is null

See this post http://balasingam.com/sql-server/update-top-n-record-in-sql-server/comment-page-1#comment-227

BaLs