21

I'm not crazy familiar with WPDB or SQL in general but I have a custom table for my project and I'm trying to assign some metadata to it. What I'd "like" to happen is if a row exists, update it and if not insert it. I've read both Insert and Update in the WPDB Codex but neither really went into an "either or" situation. I thought i could work with update, so my code so far looks like this:

$wpdb->update(
    $wpdb->prepare(
        $wpdb->prefix.'item_info',
        array(
            'post_id'       => $post_id,
            'item_stock'    => $item_stock
        ),
        array('post_id' => $post_id)
    )
);

Does WordPress have anything like an "IF exists Update, ELSE Insert", or do I need to run custom SQL to achieve this, or do I need to query the database first to see if an ID exists in my table THEN decide whether to update it or insert it?

23

First, you are using prepare incorrectly. You seem to have $wpdb->update's arguments wrapped in $wpdb->prepare like that. That won't work. In effect, you are passing update a single argument-- the output of prepare. Try something simple like the following and you will see why that won't work:

$post_id = 123;
$item_stock = 567;
var_dump(
  $wpdb->prepare(
    $wpdb->prefix.'item_info',
    array(
        'post_id'       => $post_id,
        'item_stock'    => $item_stock
    ),
    array('post_id' => $post_id)
  )
);

And $wpdb->update() runs prepare for you.

Second, if this were me, I skip the helper function bloat and write a proper ON DUPLICATE KEY UPDATE query:

$sql = "INSERT INTO {$wpdb->prefix}item_info (post_id,item_stock) VALUES (%d,%s) ON DUPLICATE KEY UPDATE item_stock = %s";
// var_dump($sql); // debug
$sql = $wpdb->prepare($sql,$post_id,$item_stock,$item_stock);
// var_dump($sql); // debug
$wpdb->query($sql);

This assumes that post_id is a UNIQUE index or PRIMARY KEY. If your table structure is what I think it is, let the database handle it.

  • This was insanely useful... Thanks for your time s_ha_dum! – Jake Jul 30 '14 at 15:01
  • Prepare returns false for me - no other db errors. If running the query manually in phpmyadmin it works as expected. Also checked that variables are what they should be .. Any ideas? – trainoasis Jan 25 '16 at 8:37
  • 1
    What if post_id isn't the PRIMARY KEY? – Mike Kormendy Nov 29 '16 at 0:36
18

Have you tried $wpdb->replace. According to WP Codex:

Replace a row in a table if it exists or insert a new row in a table if the row did not already exist.

I have tried myself in some plugins and it does the work when trying to avoid unique IDs duplication errors, etc.

More info in the codex

  • This worked for me while custom query did not - thanks for mentioning replace() – trainoasis Jan 25 '16 at 8:49
  • This is the correct answer to the question. – Tyler Jones Sep 20 '16 at 9:19
  • 6
    it is worth noting that $wpdb->replace is a destructive overwrite of the entire record, whereas $wpdb->update only updates the specific fields included in the $data array – MatthewLee Dec 9 '16 at 4:46
0

You should check if the row exists first.

Most likely you'll want to try to get the ID or primary key for the row you're trying to update, then $wpdb->update if it does or $wpdb->insert of it doesn't

  • 14
    An example of how to check if the ID or primary key exists would really make this a useful answer. This is almost like reiterating the question. – Jake Jul 30 '14 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.