If I enter a row with wpdb->replace using an ID that already exists, it's replaced and 2 is returned. If I enter a new row, the ID is auto generated, a new row is inserted and 1 is returned. Perfect.

If, however, I enter a row that exactly matches an existing row (where I would still expect a delete and insert), 1 is returned instead (even though no new rows are inserted in the database). Why is this happening?!

I am trying to insert a post when a row is inserted into my database. ie.) when replace returns 1. but I'm alse getting new posts when when I insert an exact copy of an existing row.

function xxxx_insert_entry( $post_id, $entry, $type, $entry_id = null ) {
    global $wpdb;

    $result = $wpdb->replace( 
        $wpdb->prefix . 'xxxx_entries', 
            'ID' => $entry_id, // PRIMARY KEY
            'post_id' => $post_id,
            'entry' => $entry, 
            'type' => $type 
    if ( $result === false ) return $result;

    $insert_id = $wpdb->insert_id;

    if ( 1 == $result ){ // INSERT OCCURRED
        $args = array(
            'post_type'     => 'entry',
            'post_title'    => $entry,
            'post_status'   => 'publish',
            'meta_input'    => array( 'entry_id' => $insert_id ),
        wp_insert_post( $args, true );


    return $insert_id;

1 Answer 1


I have found here that;

It is possible that in the case of a duplicate-key error, a storage engine may perform the REPLACE as an update rather than a delete plus insert, but the semantics are the same.

Which would return 1 row affected on what should otherwise be a delete and insert.

I am now checking if an entry_id was provided to the function. ie. if I was expecting an insert.

    if ( 1 == result || isset( $entry_id ) ) 

Your Answer

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

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