views:

2819

answers:

6

I would like to use "ON DUPLICATE KEY UPDATE" in Zend Framework, is this possible?

Example

INSERT INTO sometable (...) VALUES (...) ON DUPLICATE KEY UPDATE ...

A: 

If your doing something like this, then most likely your design is flawed.

masfenix
Why? You shouldn't have to query the DB to find if something exists and then do something if it does and do something if it doesn't.
Thomas Owens
While a design-flaw might be an answer, and yes I can I could effective-date every row and just find the latest one, I don't want this table to get totally out of hand because it is being updated via an AJAX call, which might happen alot with 300,000 users. So nope this isnt the correct answer.
danielrsmith
There are legitimate uses for ON DUPLICATE KEY UPDATE, and many database experts agree, hence it is included in the standard SQL language.
Bill Karwin
A: 

I was searching for this also long time, but finally I found answer only to write own sql query. Something like: $db->query('INSERT INTO table ( column ... ... ) VALUES( "'.$value.'" ... ... )

  ON DUPLICATE KEY UPDATE 
   column = "'.$value.'"
  ');

I don't found another solution

harvejs
+8  A: 

I worked for Zend and specifically worked on Zend_Db quite a bit.

No, there is no API support for the ON DUPLICATE KEY UPDATE syntax. For this case, you must simply use query() and form the complete SQL statement yourself.

I do not recommend interpolating values into the SQL as harvejs shows. Use query parameters. Note that you have to repeat the list of values:

$sql = "INSERT INTO sometable (id, col2, col3) VALUES (?, ?, ?)
  ON DUPLICATE KEY UPDATE id = ?, col2 = ?, col3 = ?";

$values = array("id"=>1, "col2"=>327, "col3"=>"active");

$db->query($sql, array_merge(array_values($values), array_values($values)));

I included id = ? even though it's obviously a no-op when the key is a duplicate, but it's handy to include it because it's easier to clone the array of values when I don't have to remove the first entry.

Bill Karwin
Yes that is what I had done as well, I was really wondering if there was a method of Zend_Db_... that provides that functionality so maybe instead of using $db->insert() we can use $db->insertOrUpdate() ... just an idea.
danielrsmith
No, there is no such method in Zend_Db. The goal of the ZF product was always to provide simple solutions to the 80% most common cases.
Bill Karwin
You can extend it and add this feature easily ;)
Tomáš Fejfar
Yes of course, but another goal was to avoid making special methods for proprietary SQL features for any brand of database.
Bill Karwin
Minor nitpick: you should use quotes around array keys, otherwise PHP will try to evaluate them as constants.
fireeyedboy
@fireeyedboy: Thanks, I've edited my answer above.
Bill Karwin
+2  A: 

@Bill Karwin: great solutions! But it would be greater if to use named placeholders (":id", ":col1", …) instead of questions signs. Than you wouldn’n need to duplicate values by array_marge. Also if to use "SET" syntax of "INSERT" instead of "VALUES", the code gets simplier to be generated automatically for any set of fields.

$sql = 'INSERT INTO sometable SET id = :id, col2 = :col2, col3 = :col3
    ON DUPLICATE KEY UPDATE id = :id, col2 = :col2, col3 = :col3';
Sergei Morozov
A: 

As a sidebar to the accepted answers on this thread, you can simplify the ON DUPLICATE KEY UPDATE clause and reduce the amount of processing your script needs to do by using VALUES():

$sql = 'INSERT INTO ... ON DUPLICATE KEY UPDATE id = VALUES(id), col2 = VALUES(col2), col3 = VALUES(col3)';

http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

Phoenix
A: 

you can simply do something like this:

set unique index on your id

and then

try {
   do insert here
} catch (Exception $e) {
   do update here
}
Peter