Manually delete post from database

The question:

For whatever reason, I have a post and a page with the same slug name and it causes the db to hang. I can’t alter the slug on either so I need to go manually delete the posts from the database and start over.

Now, I am willing to go pull up the post ID from wp_posts and wp_postmeta and manually delete each entry. Will this screw up anything else in the database assuming I have no comments on either post or page?

EDIT

I found this script and I think it’s ok but I’m not sure if this takes care of revisions or anything else I would leave behind from manually deleting the post

DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
WHERE a.ID = xxx;

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Drop this into a file in your plugin directory and you should be able to do this from your WP installation using a query string.

/*
Plugin Name: Delete Specific Post
Description: Rid the post forever!
Version: 0.1
Author: WPSE
License: GPL2
*/

add_filter('query_vars', 'delete_post_query_var');
function delete_post_query_var($vars){
    $vars[] = 'delete_post';
    return $vars;
}

add_action('admin_init', 'manually_delete_post', 0);
function manually_delete_post(){

    if(!is_user_logged_in())
        return;

    if(!current_user_can('manage_options'))
        return;

    if(get_query_var('delete_post')){
        $id = esc_attr(get_query_var('delete_post'));
        $delete = wp_delete_post($id, true); //True force deletes the post and doesn't send it to the Trash
        if($delete)
            echo "Post $id deleted successfully!";
        else
            echo "Post $id was not deleted.";
        exit;
    }
}

All you need to do is make sure you’re logged into an administrator account, then visit: http://yourdomain.com/wp-admin/?delete_post=POSTID

Method 2

I recently had this issue with a post-type I wanted to nuke, relationships everywhere and no DB enforced FK cascade.

/* DELETE REVISIONS */
DELETE posts
FROM
    `prefix_posts` AS posts
INNER JOIN `prefix_posts` AS parents ON posts.post_parent = parents.ID
WHERE
    parents.post_type = "myposttype"; /*REPLACE W/ parents.ID = "yourID"*/


/* DELETE POSTS */
DELETE
FROM
    `prefix_posts`
WHERE
    post_type = "myposttype"; /*REPLACE W/ ID = "yourID"*/


/* DELETE ORPHANED POST META */
DELETE
FROM
    `prefix_postmeta`
WHERE
`prefix_postmeta`.`post_id` NOT IN(
    SELECT
        `prefix_posts`.`ID`
    FROM
        `prefix_posts`
);

Are you using any plugins that create tables? (like post-2-post)

/* ORPHANED POST2POSTS */
DELETE
FROM
    `prefix_p2p`
WHERE
    `prefix_p2p`.`p2p_from` NOT IN(
        SELECT
            `prefix_posts`.`ID`
        FROM
            `prefix_posts`
);

DELETE
FROM
`prefix_p2p`
WHERE
    `prefix_p2p`.`p2p_to` NOT IN(
        SELECT
            `prefix_posts`.`ID`
        FROM
            `prefix_posts`
    );

its probably easier to use the built in WP functions… but if you need SQL calls for this look above.

Method 3

why not simply use wp_delete_post() ?

When the post and page goes, everything that is tied to it is deleted also. This includes comments, post meta fields, and relationships between the post and taxonomy terms.

Method 4

Expanding on @Brian Fegter’s answer Above you could use the below plugin to remove posts in bulk. It creates a WP admin page with a text area for ids of pages/posts to remove.

<?php

/*
Plugin Name: Delete Posts By ID
Description: Delete posts and pages by id
Version: 0.1
Author: WPSE
License: GPL2
*/


add_action( 'admin_menu', 'deletePostsMenu' );

function deletePostsMenu() {
    add_menu_page(
        'Delete Posts',
        'Delete Posts',
        'manage_options',
        'delete-posts/delete-posts-admin-page.php',
        'delete_posts_admin_page',
        'dashicons-trash',
        6
    );
}

function delete_posts_admin_page() {
    ?>
    <div class="wrap">
        <h2>Delete Posts By ID</h2>
        <p>Add post/page ids separated by a line break</p>
        <form action="" method="post">
            <label for="deletePostsByID"></label>
            <textarea name="deletePostsByID" id="ids" cols="30" rows="10"></textarea>
            <input type="submit">
        </form>
    </div>
    <?php

    if (isset($_POST['deletePostsByID'])) {
        delete_posts($_POST['deletePostsByID']);
        return;
    }
}

//add_action('admin_init', 'manually_delete_post', 0);
function delete_posts($submittedIDs){

    if(!is_user_logged_in())
        return;

    if(!current_user_can('manage_options'))
        return;

   /* // Strip whitespace
    $stripped = str_replace(' ', '', $submittedIDs);*/

    // Set to array
    $idsArray = explode("rn",$submittedIDs);

    echo '<ol>';
    // Delete posts by id
    foreach ($idsArray as $id){
        $delete = wp_delete_post($id, false); //True force deletes the post and doesn't send it to the Trash
        if($delete)
            echo "<li>Post $id deleted successfully!</li>";
        else
            echo "<li>Post $id was not deleted.</li>";

    }

    echo '</ol>';

    exit;
}

Method 5

Ok, if you want to delete it completely, you have to delete post/page from wp_term_relationships table. But if the issue is only in the slug, you can update appropriate record in database and your slugs will be fixed. To update slug you need to run such query:

UPDATE wp_posts SET post_name = 'my-new-slug' WHERE ID = /*your post ID here*/


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment