1

我想对 WordPress 站点(wp_postmeta 表)中的帖子元数据执行一些更新。已知的 good'ol 函数update_post_meta()正在完成这项工作,并且还将检查,如果密钥不存在,它将添加它。但是,此功能一次只能处理一篇文章。我想节省昂贵的数据库调用,并使用一个查询更新不同帖子 ID 的多个字段。

一般来说,我可以使用 mySQLUPDATE查询CASE来切换和分配每个meta_valuepost_id就像在这个例子中一样,并更新表中不同行的一些值。但是,对于某些帖子,可能meta_key尚不存在,因此INSERT需要而不是更新。好吧,如果不使用update_post_meta(),我应该以某种方式检查一下。我尝试使用INSERT .... ON DUPLICATE UPDATE( syntax ) 和REPLACE( syntax ),但它仅与唯一或定义为主键的列相关,因此在这种情况下没有帮助。

有没有一种方法或想法,我如何拥有“插入值,如果已经存在这个 post_id 的这个 meta_key 则更新”,并为几个不同的 post_ids 执行此操作(相同的 meta_key,但一路上),并使用一个单一的 mySQL 查询?

谢谢(* 我也在 WordPress 答案中问过这个问题,也在这里问过)

4

1 回答 1

4

REPLACE并且INSERT ... ON DUPLICATE KEY UPDATE不是“仅与唯一或定义为主键的列相关”,而是根据是否存在唯一键冲突来确定记录是新的还是已经存在的(因此需要替换/更新)或不。正如MySQL 文档所述:

REPLACEMySQL 对(and )使用以下算法LOAD DATA ... REPLACE

  1. 尝试将新行插入表中

  2. 由于主键或唯一索引发生重复键错误,插入失败:

    一种。从表中删除具有重复键值的冲突行

    湾。再次尝试将新行插入表中

它的描述INSERT ... ON DUPLICATE KEY UPDATE 类似

因此,如果您的REPLACEorINSERT ... ON DUPLICATE KEY UPDATE命令通过它们当前的主键标识您更新的记录,它应该完全按照您的意愿行事。根据WordPress 文档,主键是meta_id字段,因此使用 aSELECT获取现有案例的此标识符并使​​用外部连接,获取NULL它是否不存在(将列设置为下一个auto_increment):

REPLACE INTO `wp_postmeta` (
      `meta_id`
    , `post_id`
    , `meta_key`
    , `meta_value`
)
    SELECT
          `meta_id`
        , `post_id`
        , "key of interest"
        , "new value" -- assuming all posts to be set the same
    FROM
        `wp_postmeta`
        NATURAL RIGHT JOIN (
           SELECT 1 AS `post_id` -- where 1 is the first post_id
           UNION SELECT 2        -- 2 is the second
           UNION SELECT 3        -- 3 is the third
           -- etc.
        ) AS `temp_table`
    WHERE
        `meta_id` IS NULL OR `meta_key` = "key of interest"
;

如果每个帖子的新元值都不同,您可以添加这样的值作为第二列temp_table

REPLACE INTO `wp_postmeta` (
      `meta_id`
    , `post_id`
    , `meta_key`
    , `meta_value`
)
    SELECT
          `meta_id`
        , `post_id`
        , "key of interest"
        , `new_value`
    FROM
        `wp_postmeta`
        NATURAL RIGHT JOIN (
           SELECT 1 AS `post_id`, "foo" AS `new_value`
           UNION SELECT 2, "bar"
           UNION SELECT 3, "qux"
           -- etc.
        ) AS `temp_table`
    WHERE
        `meta_id` IS NULL OR `meta_key` = "key of interest"
;
于 2012-04-22T16:11:56.680 回答