如果元数据不存在,则立即为CPT中的所有帖子插入帖子元数据

时间:2017-07-28 作者:freejack

我制作了一个使用CPT和一些元数据的插件。该插件有两个版本A和B。

版本A有一个帖子元小于版本B,称为“得分”。当用户将插件从A更新到B时,我需要为版本B的所有自定义帖子创建分数元才能正常工作。

这是我使用的插入查询:

global $wpdb;

$wpdb->query(
    "
    INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value)
    SELECT p.ID, \'score\' AS meta_key, 0 AS meta_value
    FROM $wpdb->posts AS p
    WHERE p.post_type = \'my_cpt\'
    "
);
此查询用于添加新元数据,但如果多次运行,将创建重复的元数据。我应该怎么做才能使查询仅在元数据不存在的情况下添加元数据?

感谢您提供任何可能的解决方案。

2 个回复
最合适的回答,由SO网友:freejack 整理而成

对任何感兴趣的人来说,这是一个对我有用的问题:

INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value)
SELECT p.ID, \'score\' AS meta_key, 0 AS meta_value
FROM $wpdb->posts AS p
WHERE p.post_type = \'my_cpt\'
AND p.ID NOT IN (
    SELECT p2.ID 
    FROM $wpdb->posts AS p2
    INNER JOIN $wpdb->postmeta AS pm
    ON pm.post_id = p2.ID
    WHERE pm.meta_key = \'score\'
)
但阅读之后this article 为了获得更好的性能,我宁愿将查询一分为二:

global $wpdb;

//Get all posts which already have the metadata
$not_in = $wpdb->get_results( 
    "
    SELECT p.ID
    FROM $wpdb->posts AS p
    INNER JOIN $wpdb->postmeta AS pm
    ON pm.post_id = p.ID
    WHERE pm.meta_key = \'score\'
    AND p.post_type = \'my-cpt\'
    AND p.post_status NOT IN (\'draft,auto-draft\')",
    ARRAY_A
);

//Make results into string
$not_in = ! empty($not_in) ? implode( \',\', array_column( $not_in, \'ID\' ) ) : \'\';

//Insert new metadata
$wpdb->query(
    "
    INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value)
    SELECT p.ID, \'score\' AS meta_key, 0 AS meta_value
    FROM $wpdb->posts AS p
    WHERE p.post_type = \'my-cpt\'
    AND p.ID NOT IN ( $not_in )
    "
);

SO网友:kero

你只想INSERT 对于还没有此邮戳的帖子。所以你需要改变你的SELECT 只有这些。

我只是尝试了几件事,看起来很棘手。下面是对我有用但代价高昂的查询。因为这只会在插件激活时运行,所以性能应该不会有太大问题。

INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value)
SELECT p.ID, \'score\' AS meta_key, 0 AS meta_value
FROM $wpdb->posts AS p
WHERE p.post_type = \'my_cpt\'
AND WHERE p.ID NOT IN (
    SELECT $wpdb->posts AS p2
    INNER JOIN $wpdb->postmeta AS pm
    ON pm.post_id = p2.ID
    WHERE pm.meta_key = \'score\'
)

结束