Question

I'm trying to write an UPDATE SQL Query to clean up my database a bit...

Here's what I've tried but it did create huge problems for me and ended up not honoring all of my WHEREs which changed records that weren't supposed to be changed...

UPDATE Orders
SET Orders.OrderStatus = Cancelled
WHERE Orders.OrderStatus in (New,Pending,Processing,Payment Declined,Awaiting Payment,See Line Items,See Order Notes,Backordered)
AND Orders.Total_Payment_Received = 0

There was also a third clause. That clause did not work as well, it was designed to get all records older than sixty days, it looked like it wouldn't work and I'm not sure why I executed the code. I'm afraid to post that line here cause I'll look dumb. It was something like:

AND Orders.OrderDate BETWEEN DATEADD(Day, -60, GetDate())

So only records with OrderDate older than sixty days should be affected.

If anybody can help me compile a query that would work it'd be greatly appreciated...

Was it helpful?

Solution

I'm not completely sure if you're saying the first update is working or not, or if it's just the order date check that was causing problems, so I'll just address the order date.

If you want records older than 60 days...

and Orders.OrderDate < dateadd(day, -60, getdate())

However, since getdate() includes time, you likely want to take that out of consideration...

and Orders.OrderDate < dateadd(day, -60, convert(char(10), getdate(), 101))

The convert function in this case removes the time part of the date.

Also, if your order statuses are supposed to be strings then they need to be surrounded by quotes, so your full query would look like this:

UPDATE Orders 
SET Orders.OrderStatus = 'Cancelled'
WHERE Orders.OrderStatus in ('New','Pending','Processing','Payment Declined','Awaiting Payment','See Line Items','See Order Notes','Backordered') 
AND Orders.Total_Payment_Received = 0 
AND Orders.OrderDate < dateadd(day, -60, convert(char(10), getdate(), 101))

A word of advice on running updates. ALWAYS run a SELECT first with the same WHERE clause so you can identify which rows are going to be affected. This will save you a lot of pain. If there are too many rows that need to be updated, use SELECT TOP 5000 or something so you can at least check some of them. Always know exactly what you're going to update before you update it.

OTHER TIPS

If you want your order date must be between today's date and 60 days before you should do the following.

WHERE start_date BETWEEN dateadd(day,-60,getdate()) AND getdate();

Use query analyzer and create a view of the orders you want to cancel. Views are awesome. With views you can build the subset of data one piece at a time checking along the way that your view contains the correct subset of data. For example:

Start by creating called viewOrdersToCancel that shows all Orders with a Total_Payment_Received = 0. (This is done by putting = 0 within the filter column)

Do a SELECT * FROM viewOrdersToCancel to see just those records.

Then modify the view and add the OrderDate between DateAdd(d,-60, GetDate()), GetDate()) criteria.

Do another SELECT * FROM viewOrdersToCancel to see just those records.

Now modify the view adding the different OrderStatus values within an in clause.

Your view now contains the subset of Orders you want to set to "Cancelled"

Simply run an update statement with an inner join:
(This assumes you have a unique OrderId)

UPDATE Orders  
SET OrderStatus = 'Cancelled'  
FROM Orders t1  
INNER JOIN viewOrdersToCancel t2  
ON t1.OrderId = t2.OrderId
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top