1

我将 BatchError 与 executeMany 一起使用

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

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

我的代码:

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 是 pk):

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

我也期望 rowsAffected = 3,第一项未添加到 TABLE

谢谢

4

3 回答 3

0

在我的代码中添加 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,感谢大家的帮助 :)

于 2020-07-13T10:00:15.263 回答
0

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

于 2020-06-29T18:28:55.530 回答
0

node-oracledb 文档

请注意,某些类别的错误将始终通过 executeMany()回调错误对象返回,而不是作为批处理错误。

您可能会看到其中一种情况。您可以使用触发错误的可运行测试用例来更新您的问题吗?

不要忘记如果自动提交batchErrors生效并且出现错误,则会忽略自动提交。

于 2020-06-29T00:48:04.753 回答