views:

225

answers:

3

What I am trying to do here is: IF the records in table todo as identified in $done have a value in the column recurinterval then THEN reset date_scheduled column ELSE just set status_id column to 6 for those records.

This is the error I get from mysql_error() ...

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN SET date_sche' at line 2

How can I make this statement work?

UPDATE todo 
CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
ELSE 
SET status_id = 6 WHERE todo_id IN ($done)
END

The following mySQL statement worked just fine before I revised like above.

UPDATE todo 
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
AND recurinterval != 0 
AND recurinterval IS NOT NULL
A: 

I believe you need to add 'WHEN' after the first CASE keyword. So the beginning of the first line reads:

UPDATE todo CASE WHEN recurinterval !=0 AND ...
Dan
I tried what you suggested but I got this error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN recurinterval != 0 AND recurinterval IS NOT NULL THEN SET date' at line 2
AK
+1  A: 

The thing is that you're trying to do something that afaik is impossible to do using just one query. You want to update 1 of 2 columns based on the value of your recurinterval field. So basically you should split it up into 2 queries, the first one will be the one you had ie.

UPDATE todo 
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
AND recurinterval != 0 
AND recurinterval IS NOT NULL

And the second one will be for the other rows :

UPDATE todo 
SET status_id = 6
WHERE todo_id IN ($done) 
AND (recurinterval = 0 
OR recurinterval IS NULL)

If you run these queries (most likely you'll want to run them inside a transaction so you can rollback the changes if an error occurs during one of the queries) you should get the result you want.

wimvds
What you suggest is what I'm doing now. Because the "WHERE todo_id IN ($done)" is redundant, it seems to me that the two queries can be combined. I couldn't figure out how to implement Nick Gorbikoff's suggestion of using an IF for flow control. What do you think?
AK
A flow control function to update one of 2 fields is AFAIK not possible with SQL. Yes, the WHERE todo_id IN ... is identical, but you're also filtering on recurinterval, and so you are in fact trying to update 2 different sets of records in one go.
wimvds
A: 

Seems to me that your first case in you modified statement CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN should be actually an IF

Nick Gorbikoff
I commented to wimvds answer about your suggestion.I tested IF but received mysql_error(): Query was empty.My code."UPDATE todo IF recurinterval != 0 AND recurinterval IS NOT NULL THENSET date_scheduled = CASE recurunitWHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)ENDWHERE todo_id IN ($done) ELSE SET status_id = 6 WHERE todo_id IN ($done)END IF";
AK
Also with parenthesis like soIF (recurinterval != 0 AND recurinterval IS NOT NULL) THEN . . .I guess wimvds is correct in his response.
AK
@AK - you are using the wrong IF statement. You should be using this: IF(...) http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if - which you confused with IF ... END IF http://dev.mysql.com/doc/refman/5.0/en/if-statement.html - they are different IF statements - and have different context and use. Sorry I wasn't clear.
Nick Gorbikoff
OOPS nevermind - I just read your second comment.
Nick Gorbikoff
OK I think that VMVDS's comment is right on the money cause it makes for cleaner code and is easier to read if another person needs to do it. And now that I took a look at your statement - I think it's possible to do it with an IF (but your statement would be overblown beyond reason) - you trying to evaluate one field and set another - and IF is designed to update the field you are trying to set based on condition. So you could use an if statement to update date_scheduled but not status_id at the same time without running a subquery in your IF statement - so my vote is to stick with VMVDS's
Nick Gorbikoff