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);


5 回复

要实现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);
});

解释

  1. 数据库连接:首先创建并连接到数据库。
  2. 任务数组:为每个项目创建一个任务函数,该函数将执行查询以检查项目是否已存在。
  3. 条件判断:如果项目存在,则执行更新查询;否则执行插入查询。
  4. 错误处理:确保每个操作都正确处理可能发生的错误。
  5. 异步执行:使用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(); // 关闭数据库连接
});

解释:

  1. SQL 防注入:使用参数化查询来防止 SQL 注入攻击。
  2. 异步处理:每个任务使用 async 库中的 series 方法按顺序执行。
  3. 错误处理:如果查询过程中发生错误,抛出异常并终止执行。

这段代码会依次检查列表中的每个项是否存在,如果存在则更新,否则插入新记录。

回到顶部