WooCommerce:如何将旧规格变体价格批量复制到新规格变体
解决WooCommerce变体价格批量复制问题(旧规格→新规格)
需求背景
我们在WordPress+WooCommerce环境下拥有6000+产品,已删除Size 1/Size 2/Size 3尺寸属性,新增Size 4/Size 5属性。当前状态:
- 旧规格变体因属性删除变为空变体,但
_regular_price元数据仍保留 - 通过PW Bulk Edit创建的新规格变体(Size4/Size5)暂无价格
需实现:按Size 1 > Size 2 > Size 3的优先级,将对应旧变体的_regular_price复制到同父产品下的新变体(Size4/Size5)中。
数据库表结构示例
wp_posts表(产品/变体基础数据)
| ID | post_type | post_parent | post_title | post_status |
|---|---|---|---|---|
| 100 | product | 0 | 示例T恤 | publish |
| 101 | product_variation | 100 | 示例T恤 - 空变体(原Size1) | publish |
| 102 | product_variation | 100 | 示例T恤 - 空变体(原Size2) | publish |
| 103 | product_variation | 100 | 示例T恤 - Size4 | publish |
| 104 | product_variation | 100 | 示例T恤 - Size5 | publish |
wp_postmeta表(元数据)
| meta_id | post_id | meta_key | meta_value |
|---|---|---|---|
| 2001 | 101 | _regular_price | 29.99 |
| 2002 | 102 | _regular_price | 34.99 |
| 2003 | 103 | _regular_price | (空) |
| 2004 | 104 | _regular_price | (空) |
| 2005 | 101 | _product_attributes | (原Size1属性数据,已失效) |
| 2006 | 103 | _product_attributes | (Size4属性数据) |
预期结果
执行操作后,wp_postmeta表更新为:
| meta_id | post_id | meta_key | meta_value |
|---|---|---|---|
| 2001 | 101 | _regular_price | 29.99 |
| 2002 | 102 | _regular_price | 34.99 |
| 2003 | 103 | _regular_price | 29.99 |
| 2004 | 104 | _regular_price | 29.99 |
| 2005 | 101 | _product_attributes | (原Size1属性数据,已失效) |
| 2006 | 103 | _product_attributes | (Size4属性数据) |
可行实现方法
方法1:直接执行MySQL脚本(需先备份数据库)
该脚本会按优先级找到每个父产品下最高优先级的旧变体价格,批量更新新变体的_regular_price:
-- 临时表存储每个父产品的最高优先级旧价格 CREATE TEMPORARY TABLE temp_parent_prices AS SELECT p.post_parent, MAX(CASE WHEN pm.meta_value LIKE '%Size 1%' THEN pm2.meta_value WHEN pm.meta_value LIKE '%Size 2%' THEN pm2.meta_value WHEN pm.meta_value LIKE '%Size 3%' THEN pm2.meta_value ELSE NULL END) AS highest_price FROM wp_posts p JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_product_attributes' JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_regular_price' WHERE p.post_type = 'product_variation' AND (pm.meta_value LIKE '%Size 1%' OR pm.meta_value LIKE '%Size 2%' OR pm.meta_value LIKE '%Size 3%') GROUP BY p.post_parent; -- 更新新变体的空价格 UPDATE wp_postmeta new_pm JOIN wp_posts new_p ON new_pm.post_id = new_p.ID JOIN temp_parent_prices tpp ON new_p.post_parent = tpp.post_parent SET new_pm.meta_value = tpp.highest_price WHERE new_p.post_type = 'product_variation' AND new_pm.meta_key = '_regular_price' AND new_pm.meta_value = '' AND EXISTS ( SELECT 1 FROM wp_postmeta attr_pm WHERE attr_pm.post_id = new_p.ID AND attr_pm.meta_key = '_product_attributes' AND (attr_pm.meta_value LIKE '%Size 4%' OR attr_pm.meta_value LIKE '%Size 5%') ); -- 删除临时表 DROP TEMPORARY TABLE temp_parent_prices;
注意:执行前务必备份数据库,替换表前缀
wp_为你的实际前缀。
方法2:WordPress PHP代码(更安全,适合非数据库管理员)
将以下代码添加到主题的functions.php或自定义插件中,访问任意前端页面一次后删除执行代码:
function copy_old_variation_prices_to_new() { // 获取所有已发布的父产品 $parent_products = get_posts([ 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => 'publish', ]); foreach ($parent_products as $parent) { $target_price = ''; // 按优先级获取旧变体的有效价格 $old_variations = get_posts([ 'post_type' => 'product_variation', 'posts_per_page' => -1, 'post_parent' => $parent->ID, 'post_status' => 'publish', 'meta_query' => [ 'relation' => 'OR', ['key' => '_product_attributes', 'value' => 'Size 1', 'compare' => 'LIKE'], ['key' => '_product_attributes', 'value' => 'Size 2', 'compare' => 'LIKE'], ['key' => '_product_attributes', 'value' => 'Size 3', 'compare' => 'LIKE'], ], ]); // 遍历旧变体,取第一个有效价格(优先级最高) foreach ($old_variations as $var) { $price = get_post_meta($var->ID, '_regular_price', true); if (!empty($price)) { $target_price = $price; break; } } if (!empty($target_price)) { // 更新同父产品下的新变体空价格 $new_variations = get_posts([ 'post_type' => 'product_variation', 'posts_per_page' => -1, 'post_parent' => $parent->ID, 'post_status' => 'publish', 'meta_query' => [ 'relation' => 'AND', ['key' => '_regular_price', 'value' => '', 'compare' => '='], [ 'relation' => 'OR', ['key' => '_product_attributes', 'value' => 'Size 4', 'compare' => 'LIKE'], ['key' => '_product_attributes', 'value' => 'Size 5', 'compare' => 'LIKE'], ] ] ]); foreach ($new_variations as $new_var) { update_post_meta($new_var->ID, '_regular_price', $target_price); // 可选:同步促销价 // update_post_meta($new_var->ID, '_sale_price', $target_price); } } } } // 执行函数,访问页面后立即删除此行 add_action('init', 'copy_old_variation_prices_to_new');
注意:执行完成后,请删除
add_action('init', ...)这一行,避免重复执行。
内容的提问来源于stack exchange,提问作者John Adams
相关产品推荐
相关产品推荐

