SQL 2005 Update Query
-
11-12-2019 - |
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...
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