Node.js + Oracledb + executeMany + batchErrors + Promise:如果一个错误不执行所有

Node.js + Oracledb + executeMany + batchErrors + Promise: does not execute all if one error

iam 将 BatchError 与 executeMany 结合使用

如果没有错误..一切正常

但是如果一个或多个错误.. 它不会执行。它给出 rowsAffected = error row number

我的代码:

const oracledb = require('oracledb');

async function post(req, res, next) {
    try {
      let user = {};
      user = await create();
  
      res.status(201).json(user);
    } catch (err) {
      next(err);
    }
  }
  
  module.exports.post = post;


  const sql =
  `INSERT INTO TABLE (
     USER_CODE, 
     USER_NAME,
     STAFF_ID,
     ROLE_ID,
     TEAM_CODE,
     GRP_ID,
     MOBILE_NUMBER
   ) VALUES (
     :USER_CODE,
     :USER_NAME,
     :STAFF_ID,
     :ROLE_ID,
     :TEAM_CODE,
     :GRP_ID,
     :MOBILE_NUMBER
   )`;

  async function create() {

    const data = [
      {"USER_CODE":600, "user_name": "att1", "staff_id": 660, "role_id": 1, "team_code": 20, "grp_id": 1, "mobile_number": "0101"},
      {"USER_CODE":600, "user_name": "att2", "staff_id": 661, "role_id": 1, "team_code": 20, "grp_id": 1, "mobile_number": "0102"},
      {"USER_CODE":602, "user_name": "att3", "staff_id": 662, "role_id": 1, "team_code": 20, "grp_id": 1, "mobile_number": "0103"}
   ];

    let opts = {};

    let result = await manyExecute(sql, data, opts);
 
    return result;
  }
  
  module.exports.create = create;

function manyExecute(statement, binds, opts) {
    return new Promise(async (resolve, reject) => {
      let conn;
  
      opts.outFormat = oracledb.OBJECT;
      opts.autoCommit = true;
      opts.batchErrors = true;

      console.log(opts);
  
      try {
        conn = await oracledb.getConnection();
  
        result = await conn.executeMany(statement, binds, opts);
  
        resolve(result);
      } catch (err) {
        reject(err);
      } finally {
        if (conn) { // conn assignment worked, need to close
          try {
            await conn.close();
          } catch (err) {
            console.log(err);
          }
        }
      }
    });
  }
  
  module.exports.manyExecute = manyExecute;

如果我执行上面的代码,就会出现这个错误(USER_CODE is pk):

{ "rowsAffected": 2, "batchErrors": [ { "errorNum": 1, "offset": 1 } ] }

我预计 rowsAffected = 3 此外,第一项未添加到 TABLE

谢谢

来自node-oracledb documentation

Note that some classes of error will always return via the executeMany() callback error object, not as batch errors.

您可能遇到了其中一种情况。您可以使用触发错误的 runnable testcase 更新您的问题吗?

不要忘记,如果 batchErrors 生效并且有错误,自动提交将被忽略。

好像USER_CODE被定义为主键,这意味着它在整个table中必须是唯一的。您有两行具有相同的 USER_CODE,这违反了唯一约束集,这意味着两行中只有一行被插入而另一行失败。要解决此问题,请为每一行使用 USER_CODE 的唯一值,如果无法使其唯一,则需要重新考虑架构设计并将 USER_CODE 设为非主键列,您将需要找到另一列用作主键。

在我的代码中添加 commit() 解决了我的问题

function manyExecute(statement, binds, opts) {
    return new Promise(async (resolve, reject) => {
      let conn;
  
      opts.outFormat = oracledb.OBJECT;
      opts.autoCommit = true;
      opts.batchErrors = true;

      console.log(opts);
  
      try {
        conn = await oracledb.getConnection();
  
        result = await conn.executeMany(statement, binds, opts);
  
        resolve(result);
        await conn.commit();

      } catch (err) {
        reject(err);
      } finally {
        if (conn) { // conn assignment worked, need to close
          try {
            await conn.close();
          } catch (err) {
            console.log(err);
          }
        }
      }
    });
  }
  
  module.exports.manyExecute = manyExecute;

感谢 Dan McGhan,感谢大家的帮助:)