Node.js中MariaDB的INSERT...ON DUPLICATE KEY UPDATE无法批量增改
问题排查与解决方案
我来帮你拆解这个问题——核心原因是批量UPSERT的参数格式不符合MySQL/MariaDB驱动的要求,咱们一步步说清楚:
为什么只处理了第一条数据?
你使用的INSERT ... VALUES ?批量语法,要求?对应的参数是一个包裹着二维数组的数组(简单说就是要给你的行数组再套一层壳)。
你现在传入的参数是:
[ [ 1, 'onesize', 3 ], [ 1, 'xxs', 2 ], [ 1, 'xs', 1 ] ]
而数据库驱动(比如mysql2/mysql)会把这个二维数组的第一个子数组[1, 'onesize', 3]当成VALUES的完整参数,后面的子数组直接被忽略了。因为没有语法错误,所以程序不会报错,但只执行了第一行的更新/插入。
最优解决方案
有两种简单的修复方式,选哪种都可以:
方式1:在函数内部适配参数格式
修改你的updateQtsById函数,把传入的qtsArray再包裹一层数组传给pool.query,这样不管外部怎么传,内部都能正确解析:
updateQtsById: (qtsArray) => { return new Promise(function (resolve, reject) { pool.query( 'INSERT INTO products_qts (product_id, name, value) ' + 'VALUES ? ' + 'ON DUPLICATE KEY UPDATE ' + 'value=VALUES(value)', [qtsArray] // 关键:把行数组包在一个数组里 ) .then(result => { resolve(result.affectedRows); }) .catch(error => { reject(error); }); }); }
方式2:调用函数时调整参数格式
如果不想改函数,就在调用updateQtsById时,把参数再套一层数组:
// 原来的调用 updateQtsById([[1, 'onesize', 3], [1, 'xxs', 2], [1, 'xs', 1]]); // 改成: updateQtsById([[[1, 'onesize', 3], [1, 'xxs', 2], [1, 'xs', 1]]]);
验证逻辑
修改后,驱动会把参数正确解析为多行插入的格式:
INSERT INTO products_qts (product_id, name, value) VALUES (1, 'onesize', 3), (1, 'xxs', 2), (1, 'xs', 1) ON DUPLICATE KEY UPDATE value=VALUES(value);
这样就能批量处理所有行:存在联合主键的就更新value,不存在的就插入新行,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Antonello Gatto
相关产品推荐
相关产品推荐

