Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL server: update top(1) loop

I've been looking over other entries and it looks like I'll need a cursor? I'm relatively new but I'm swinging high with this one. Any advice or help is welcome.

UPDATE top (1) dbo.table
SET [Status] = 1
WHERE [OrderId] = '1337' and [Status] = 0;
GO               

If a record has an OrderID of 1337 and a status of 0, I want it to be changed to a 1, but this must be done one at a time.

Edit: I would like to make it loop until there are no [Status] = 0

like image 351
Super Markio Avatar asked May 28 '13 16:05

Super Markio


People also ask

Can we use top with update in SQL?

In SQL, an UPDATE statement modifies existing records of a table. You may choose to update entire columns or update rows filtered with a WHERE statement. As we'll see in this article, you can also update rows for a specified quantity from the top of your table.

How do you update a loop record?

For a loop record variable, we need an Assignment flow element to assign values to fields that we will update in this flow. We will assign today's date as the last completed task date field on the contact record and the id of the contact record to the whoId of the Loop record variable.

How to update top n records in SQL?

UPDATE TOP (100) table_name set column_name = value; If you want to show the last 100 records, you can use this if you need. Show activity on this post. The TOP qualifier can also be used as limit the the number of rows manually updated incorrectly.

How do I make my SQL Server update statement faster?

Best practices to improve SQL update statement performance We need to consider the lock escalation mode of the modified table to minimize the usage of too many resources. Analyzing the execution plan may help to resolve performance bottlenecks of the update query. We can remove the redundant indexes on the table.


2 Answers

WHILE 1=1
    BEGIN
    UPDATE top (1) dbo.table
    SET [Status] = 1
    WHERE [OrderId] = '1337' and [Status] = 0

    IF @@ROWCOUNT = 0
        BREAK
    END
like image 172
Andomar Avatar answered Oct 22 '22 11:10

Andomar


I'll throw my answer in the mix, too. I use this in production systems where I need to make updates in small batches. You can change the select top 100 PKid to top 1 if you'd like to go in batches of one. This method allows you to scale the batches of updates to something reasonable, finding a good compromise between minimal locks and set-based updates. Obviously, this adds overhead over a single set-based statement, but the OP asked.

Note: I'm guessing there is a PK field on the table, and I just gave it an assumed name of PKid

declare @done bit = 0x0;
declare @inputs table (PKid int primary key)

while @done = 0x0
begin
    -- clear the temp table variable
    delete from @inputs

    -- build the small batch up updates into table variable
    insert into @inputs (PKid) 
    select top 100 PKid from dbo.table where [Status] = 0 and OrderId = '1337'

    -- if we inserted zero records, set our @done bit to 'true' so the while loop breaks
    if @@rowcount = 0
    begin
        select @done = 0x1
    end

    -- make the update to the real table, constrained by the temp table variable
    update  t
    set     t.[Status] = 1
    from    dbo.table as t
    join    @inputs as i
    on      i.PKid = t.PKid
end
like image 22
tommy_o Avatar answered Oct 22 '22 11:10

tommy_o