Knex.js结合mysql2执行upsert时如何获取插入与更新的行数
Knex.js + MySQL2 upsert 操作获取插入/更新行数方案
你使用的MySQL语法下的upsert(INSERT ... ON DUPLICATE KEY UPDATE)本身有固定的结果计数规则,配合Knex返回的执行结果就可以计算出对应数值,具体操作如下:
1. 读取执行结果的affectedRows字段
首先调整你的代码拿到upsert操作的返回结果:
const upsertResult = await this.knex("tableName") .insert(arrayOfObjects) .onConflict(["primaryKey1", "primaryKey2"]) .merge()
MySQL2驱动返回的upsertResult第一个元素就是操作结果对象,里面的affectedRows字段是MySQL返回的操作影响行数,计数规则为:
- 无冲突成功插入1条,计数+1
- 有冲突成功更新1条,计数+2
2. 计算插入、更新行数
用以下公式即可算出两类操作的实际行数:
const totalInput = arrayOfObjects.length const affectedRows = upsertResult[0].affectedRows const updatedRows = affectedRows - totalInput const insertedRows = totalInput - updatedRows
注意事项
- 该计数规则仅适用于MySQL数据库,其他数据库的upsert影响行数逻辑不同,无法套用该公式
- 如果merge操作更新的字段值和数据库原有值完全一致,MySQL默认不会判定为有效更新,不会给对应行加2计数,此时计算出的更新行数会小于实际命中冲突的行数。如果需要强制统计所有命中冲突的行,哪怕值不变也计入更新,可以在merge时添加一个无意义的强制更新逻辑,比如:
.merge({ // 你的原有更新字段 ...updateFields, // 强制触发更新计数的冗余字段 update_time: this.knex.raw('update_time') })
内容的提问来源于stack exchange,提问作者cwallenwein
相关产品推荐
相关产品推荐

