javascript - 具有 50 多列的 DUPLICATE KEY UPDATE 上的批量插入
问题描述
我正在使用 Node.js 和 MySQL 插入 500 多行和 50 多列,如果键已经存在,则更新该行。
已经有 StackOverflow 帖子解释了如何批量插入以及如何批量插入 + 更新,但是这些解决方案不能很好地适应许多列。对于应该更新的每一列,column_name = VALUES(column_name)
如果您有 50 多列,他们建议添加确实很烦人的添加。关于如何更快地实现这一目标的任何建议?
解决方案
我通常使用类似于下面概述的方法来完成此操作。这提供了一个模型,不知道有多少列或列名是什么。我使用它的一个版本作为函数,并传递一个对象和表名,这两者都可以利用,因此这适用于多个表。只需确保在构建对象时它们具有与目标表的列名匹配的键。
// an example element with multiple objects each containing the
// same key/value structure in my case this is often the result
// set of a prior query
let test_payload = [
{
record_id: 1001,
value_1: 'robot',
value_2: null,
value_3: 'cat'
},
{
record_id: 1002,
value_1: 'robot',
value_2: null,
value_3: 'dog'
},
{
record_id: 9001,
value_1: 'robot',
value_2: 'cat',
value_3: "dog"
}
];
// let the column name strings of the query be taken from the first
// object in your set
let the_keys = Object.keys(test_payload[0]);
// a placeholder for our UPDATE string
let updates = ''
// loop through the_keys and extend the string
for (var i = the_keys.length - 1; i >= 0; i--) {
updates += `${the_keys[i]} = VALUES(${the_keys[i]})`
// add a comma and space after every
// entry but the last
i > 0 ? updates += ', ' : ' '
}
// let the VALUES be mapped from the values of your objects into an
// array of arrays
let values = test_payload.map( obj => the_keys.map( key => obj[key]));
// build a query for your column names and pass your values using the
// standard question mark place holder. 1 example first and the query.
// an alternate query approach below to consider with explanation
// 1. and example for your specific use case
let sql = 'INSERT INTO table_name (' + the_keys.join(',') + ') VALUES ? ON DUPLICATE KEY UPDATE ' + updates + ';';
// call the query function and pass it your query string, along with values
db.query(sql, [values], function (error, results) {
if (error) throw error;
console.log('query results:', results);
// do something else with your results…
});
// it is sometimes my personal preference to maintain a column such as
// update_count which can be leveraged to gauge what number of the total query
// are inserts vs update. if no value changes on an exiting record, no update
// will be counted in results.changedRows count - this approach ensures at least
// one value is always updated and registers in results.changedRows
let sql_example_with_update_count = 'INSERT INTO table_name (' + the_keys.join(',') + ') VALUES ? ON DUPLICATE KEY UPDATE update_count = update_count + 1;';
// for reference of each built item:
console.log(the_keys)
["record_id", "value_1", "value_2", "value_3"]
console.log(updates)
"value_3 = VALUES(value_3), value_2 = VALUES(value_2), value_1 = VALUES(value_1), record_id = VALUES(record_id)"
console.log(values)
[[1001, "robot", null, "cat"], [1002, "robot", null, "dog"], [9001, "robot", "cat", "dog"]]
此示例假设您知道如何初始化和使用连接。如果没有,您可以查看此示例:https ://github.com/dusthaines/mysqljs_setup_snippet/blob/master/app.js
推荐阅读
- python - 让 mod-wsgi 运行使用 python3 编写的应用程序时出现问题
- mod-rewrite - 强制 RewriteRule 结束 htaccess 文件中的处理/循环
- json - 如何使用 get_json_object 从 json 字符串中检索多个 json 字段
- sql - 如何在没有子查询的情况下做到这一点?
- pandas - Python:如何在类外使用构建在类内的数据框?
- php - 错误用户在 Heroku 上上传文件但不是本地文件
- flutter - 寻找有关实施状态以从 ListView 添加/删除的建议
- reactjs - TypeError: Object(...) is not a function with "useCallBack" ,在 React 版本 16.13.1
- javascript - JavaScript createElement polyline 和 svg 正确
- c# - 使用 SignalR 的 Blazor wasm 网络摄像头