2

I have a program that needs to synchronize it's frequently changing values (in temporary memory) with a database. The critical key (not primary!) in that table is the column id. My program changes the id but keeps the old id in memory, too.

Now, I would like to update several specified columns for multiple records/rows in one single statement. Furthermore, it should be reasonably fast for 5 up to 10 of such statements in 1 second with 4 GB RAM and ~ 50 MBit/s connection that is not only used for these sql-calls.

My sql-specifications

  • Server: 127.0.0.1 via
  • TCP/IP
  • Software: MySQL
  • Software version: 5.5.27 - MySQL Community Server (GPL)
  • Protocol version: 10
  • Server charset: UTF-8 Unicode (utf8)

I tried to use brackets...

UPDATE someTable
SET (id, name) = CASE id 
WHEN 1 THEN (111, "Dr. Frankenstein") 
WHEN 2 THEN (222, "the Monster") 
WHEN 3 THEN (333, "Mr. X") 
ELSE (id, name) END
WHERE id IN (1, 2, 3)

...which simply results in the following error:

#1064 - 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 '(id, name) = CASE id WHEN 1 THEN (111, "Dr. Frankenstein") WHEN 2 THEN (222,' at line 2

Know I wonder: Is there a way to do it in just one statement with the current syntax? Would it be feasable that way or should I just split it into multiple statement which is ugly in terms of the program that makes the sql-calls.

Answers and suggestions are welcome!

2 Answers 2

2

A case statement only returns one value:

UPDATE someTable
    SET id = (CASE id WHEN 1 THEN 111 WHEN 2 THEN 222 WHEN 3 THEN 333 ELSE id END),
        name = (CASE id WHEN 1 THEN 'Dr. Frankenstein'
                        WHEN 2 THEN 'the Monster'
                        WHEN 3 THEN 'Mr. X'
                        ELSE name
                END)
    WHERE id IN (1, 2, 3);

For performance, be sure you an an index on id. This will help with finding the records to update. Do note that changing the id value requires updating the index, which can be a bit longer than a normal update. However, expecting 5-10 transactions a second is reasonable.

Sign up to request clarification or add additional context in comments.

4 Comments

It's be pretty odd not to have id indexed; any self-respecting schema should already have set it as the primary key.
I made that choice because there would be a very special id-conflict otherwise. Of course, I could change the whole design of the program and database to remediate this. For The moment, I like it quick and dirty.
This solution does not work at this stage. At least my MySQL-Database disliked the semicolon after setting id. Exchaning it with a comma does the job. As in Sashi Kants answer the order is of great importance. Setting/Updating all columns before the id-column seems to be a must.
@FlorianR.Klein . . . I don't know why there was a semicolon there. A semicolon should only be at the end of the statement. I mistyped what should have been a comma.
0

Hope this works:

UPDATE someTable
SET id = CASE 
id 
WHEN 1 THEN 111
WHEN 2 THEN 222
WHEN 3 THEN 333
ELSE id END
,
 name = CASE 
id 
WHEN 1 THEN "Dr. Frankenstein" 
WHEN 2 THEN "the Monster" 
WHEN 3 THEN "Mr. X" 
ELSE name END

WHERE id IN (1, 2, 3)

2 Comments

This does not work because of the two redundant SET right before the name-assignment. There is problem in the order, too: I must switch the setting of id and name because the id is set immediately and the CASE of the name comes after the changes (find no ids because they have been altered).
Sorry, have changed that Kindly check

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.