Nodejs 若不存在则插入,存在则更新,如何实现?
Nodejs 若不存在则插入,存在则更新,如何实现?
需要更新的列表长度未知。 其他语言的话一个循环同步的写下来,非常容易。
用node写异步的就觉得比较忧伤了,我给出自己的做法,也看看大家遇到这样的需求是怎么做的。
var async = require("async");
var list = ["a", "b", "c"];
var tasks = [];
var result;
list.forEach(function(item) {
tasks.push(function() {
var qs = “select * from table where name=”" + item + “”";
db.query(qs, function(err, rows) {
var flag;
if(err) {
throw err;
}
if(rows[0]) {
flag = true;
} else {
flag = false;
};
result = {
id:rows[0].id || null,
name: name,
flag: flag
};
}
done();
})
});
tasks.push(function(done) {
var qs;
if(result.flag) {
qs = “update table set name=”" + result.name + “” where id=" + result.id;
} else {
qs = “insert into table set name=”" + result.name “”";
}
db.query(qs, function() {
done();
});
});
});
async.series(tasks);
要实现Node.js中若数据不存在则插入、存在则更新的功能,可以使用async
库来管理异步操作,并结合数据库查询和更新逻辑。以下是一个简化且更安全的实现方法,使用了async/await
语法以及参数化查询来避免SQL注入问题。
示例代码
const async = require('async');
const mysql = require('mysql'); // 假设我们使用MySQL
// 创建数据库连接
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'testdb'
});
db.connect((err) => {
if (err) throw err;
console.log('Connected to the database.');
});
const list = ["a", "b", "c"];
const tasks = [];
list.forEach((item) => {
tasks.push((done) => {
const query = `SELECT * FROM table WHERE name=?`;
db.query(query, [item], (err, results) => {
if (err) return done(err);
const row = results[0];
const id = row ? row.id : null;
const insertQuery = 'INSERT INTO table (name) VALUES (?) ON DUPLICATE KEY UPDATE name=VALUES(name)';
const updateQuery = 'UPDATE table SET name=? WHERE id=?';
if (row) {
db.query(updateQuery, [item, id], (err) => {
if (err) return done(err);
console.log(`Updated ${item}`);
done(null, { id, name: item, updated: true });
});
} else {
db.query(insertQuery, [item], (err) => {
if (err) return done(err);
console.log(`Inserted ${item}`);
done(null, { id: null, name: item, inserted: true });
});
}
});
});
});
async.series(tasks, (err, results) => {
if (err) throw err;
console.log('All operations completed:', results);
});
解释
- 数据库连接:首先创建并连接到数据库。
- 任务数组:为每个项目创建一个任务函数,该函数将执行查询以检查项目是否已存在。
- 条件判断:如果项目存在,则执行更新查询;否则执行插入查询。
- 错误处理:确保每个操作都正确处理可能发生的错误。
- 异步执行:使用
async.series
按顺序执行所有任务。
这种方法利用了MySQL的ON DUPLICATE KEY UPDATE
功能来简化插入或更新的过程,从而避免了复杂的异步逻辑。
用MongoDB吧,它有upsert可以实现
用async咯,async.forEachSeries
嗯,是用async了,写漏了。突然意识到自己写复杂了。这个地方不用保存select的状态,直接把插入或更新操作写在查找的回调里就好了……
在 Node.js 中实现“若不存在则插入,存在则更新”的功能,可以使用 async
库来处理异步操作。你的代码有一些问题,比如没有正确地处理异步回调,并且 SQL 语句可能有安全隐患。以下是改进后的代码示例:
const async = require('async');
const mysql = require('mysql'); // 假设使用 MySQL 数据库
// 创建数据库连接
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'testdb'
});
db.connect();
const list = ["a", "b", "c"];
const tasks = [];
list.forEach(item => {
tasks.push(done => {
const query = 'SELECT * FROM table WHERE name=?';
db.query(query, [item], (err, results) => {
if (err) throw err;
let sql;
if (results.length > 0) {
// 更新记录
sql = 'UPDATE table SET name=? WHERE id=?';
db.query(sql, [item, results[0].id], (err, result) => {
if (err) throw err;
console.log(`Updated ${result.affectedRows} row(s).`);
done();
});
} else {
// 插入新记录
sql = 'INSERT INTO table (name) VALUES (?)';
db.query(sql, [item], (err, result) => {
if (err) throw err;
console.log(`Inserted ${result.affectedRows} row(s).`);
done();
});
}
});
});
});
async.series(tasks, () => {
console.log('All operations completed.');
db.end(); // 关闭数据库连接
});
解释:
- SQL 防注入:使用参数化查询来防止 SQL 注入攻击。
- 异步处理:每个任务使用
async
库中的series
方法按顺序执行。 - 错误处理:如果查询过程中发生错误,抛出异常并终止执行。
这段代码会依次检查列表中的每个项是否存在,如果存在则更新,否则插入新记录。