views:

1190

answers:

4

I'm parsing a json feed routinely and need to insert only the newest users from the feed and ignore existing users.

I think what I need is ON DUPLICATE KEY UPDATE or INSERT IGNORE based on some searching but I'm not quite sure which is why I'm asking - so for example:

users
1     John
2     Bob

Partial JSON:

{ userid:1, name:'John' },
{ userid:2, name:'Bob' },
{ userid:3, name:'Jeff' }

From this feed I only want to insert Jeff. I could do a simple loop through all users and do a simple SELECT query and see if the user id is already in the table, if not I do an INSERT, however I suspect it won't be an efficient and practical method.

By the way, I'm using Zend_Db for the database interaction if anyone would like to cater a specific answer :) I don't mind a generic strategic solution though.

A: 

In the loop, you can do a update first, if no row affected, means it's a new entry. Keep track of those 'failed updates' then do an insert of them as new entries.

I'm not familiar with Zend_Db but I assume it can return whether a update affected how many row(s).

o.k.w
Somehow I misread the question for the need to update existing users if found, else insert as new. well... down-voted
o.k.w
+2  A: 

You need to define userid as a PRIMARY or UNIQUE key and use something like:

INSERT IGNORE INTO table (userid, name) VALUES (2, 'Bob');

If the userid 2 already exists it will ignore and move on to the next insert.

You can also use ON DUPLICATE KEY UPDATE on your table schema. One other alternative might be to use the REPLACE INTO syntax.

REPLACE INTO table (userid, name) VALUES (2, 'Bob');

This will try to INSERT, if the record already exists it will DELETE it before INSERTing it again.

Alix Axel
Is `INSERT IGNORE` supported in Zend_Db?
o.k.w
Honestly, NoFId.
Alix Axel
The `IGNORE` will cause the db engine to issue warnings instead of errors, so execution of the query won't stop. A drawback of this approach is that *any* error encountered will be ignored/turned to warning, not only a duplicate key.
Henrik Opel
@Henrik: I wasn't aware of the warnings vs errors feature but I've provided an alternative method to accomplish the same without using IGNORE.
Alix Axel
@eyze: I was just writing up the alternatives as well ;)
Henrik Opel
@eyze: A minor but potentially important correction - `REPLACE` will **not** do an UPDATE in case of an existing key, it will do a DELETE, followed by an INSERT.
Henrik Opel
@Henrik: You are right of course, fixed it. =)
Alix Axel
+4  A: 

The ON DUPLICATE KEY UPDATE alternative allows you to refer the update vs. insert decision to the database:

INSERT INTO table (userid, name) VALUES (2, 'Bobby');
  ON DUPLICATE KEY UPDATE name = 'Bobby';

would update the name field to 'Bobby', if an entry with userid 2 already exists.

You can use it as an alternative to the INSERT IGNORE if you supply a noneffective operation to the UPDATE:

INSERT INTO table (userid, name) VALUES (2, 'Bobby');
  ON DUPLICATE KEY UPDATE name = name;

This would do nothing if userid 2 already exists, thus avoiding the warning and swallowing of other errors you'd get when using INSERT IGNORE.


Another alternative would be REPLACE:

REPLACE INTO table (userid, name) VALUES (2, 'Bobby');

This would do a normal insert if the userid 2 does not exist yet. If it does exist, it will delete the old entry first and then insert a new one.


Be aware that both versions are MySQL specific extensions to SQL.

Henrik Opel
A: 

A question for

ON DUPLICATE KEY UPDATE

how do I know the status is update or insert, in PHP anyway to get the return status?

Update: In MySQL

Shiro
how to do it in Oracle ?
Gold