Node.JS、async和Oracle DB:SQL尝试次数过多

Node.JS、async和Oracle DB:SQL尝试次数过多,node.js,oracle,async.js,Node.js,Oracle,Async.js,使用如下代码: async.eachSeries(records, function(record, cb) { oracle.executeSql("an sql statement", { param1: val }, function(err, res) { console.log(err.message); cb(); }); }); 我得到了错误输出“SQLEXEC尝试次数超过”。我甚至在执行SQL语句的第一条记录中得到了它。我做错了什么?更新2019/06/26: 自版本2

使用如下代码:

async.eachSeries(records, function(record, cb) {
  oracle.executeSql("an sql statement", { param1: val },
  function(err, res) { console.log(err.message); cb(); });
});
我得到了错误输出“SQLEXEC尝试次数超过”。我甚至在执行SQL语句的第一条记录中得到了它。我做错了什么?

更新2019/06/26:

自版本2.2以来,驱动程序内置了对批处理SQL执行的支持。尽可能使用connection.executeMany()进行此操作。它以较少的复杂性提供了所有性能优势。有关更多详细信息,请参阅文档的Batch Statement Execute部分:

先前的答复:

当处理许多记录时,最好通过编写更多的代码和使用批量绑定来限制往返。这里有一个例子

鉴于这些目标:

create table t (
  id    number not null primary key,
  prop1 number not null,
  prop2 varchar2(50) not null
)
/

create sequence t_seq;
以下方面应起作用:

const oracledb = require('oracledb');
const config = require('./dbConfig.js');

async function insertObjects(objs) {
  const start = Date.now();
  let conn;

  try {
    conn = await oracledb.getConnection(config);

    const prop1s = [];
    const prop2s = [];

    // Split the objects up into separate arrays because the driver
    // currently only supports scalar array bindings.
    for (let idx = 0; idx < objs.length; idx += 1) {
      prop1s.push(objs[idx].prop1);
      prop2s.push(objs[idx].prop2);
    }

    const result = await conn.execute(
      ` declare
          type number_aat is table of number
            index by pls_integer;
          type varchar2_aat is table of varchar2(50)
            index by pls_integer;

          l_prop1s number_aat := :prop1s;
          l_prop2s varchar2_aat := :prop2s;
        begin
          forall x in l_prop1s.first .. l_prop1s.last
            insert into t (id, prop1, prop2) values (t_seq.nextval, l_prop1s(x), l_prop2s(x));
        end;`,
      {
        prop1s: {
          type: oracledb.NUMBER,
          dir: oracledb.BIND_IN,
          val: prop1s
        }, 
        prop2s: {
          type: oracledb.STRING,
          dir: oracledb.BIND_IN,
          val: prop2s
        }
      },
      {
        autoCommit: true
      }
    );

    console.log('Success. Inserted ' + objs.length + ' rows in ' + (Date.now() - start) + ' ms.');
  } catch (err) {
    console.error(err);
  } finally {
    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

function getObjects(count) {
  var objs = [];

  for (let idx = 0; idx < count; idx += 1) {
    objs[idx] = {
      prop1: idx,
      prop2: "Thing number " + idx
    };
  }

  return objs;
}

const objs = getObjects(500);

insertObjects(objs);
const oracledb=require('oracledb');
const config=require('./dbConfig.js');
异步函数插入对象(objs){
const start=Date.now();
让康涅狄格州;
试一试{
conn=await oracledb.getConnection(配置);
常量prop1s=[];
常量prop2s=[];
//将对象拆分为单独的数组,因为驱动程序
//目前只支持标量数组绑定。
for(让idx=0;idx

它使用驱动程序的execute方法,但是您可以适应包装器。此外,虽然我使用一次性连接,但大多数应用程序都应该使用连接池。

结果表明,错误来自内部Oracle包装程序,该包装程序存在一些问题。直接使用Oracle驱动程序功能为我解决了这个问题。

Oracle来自哪里?oracle(节点oracledb)的驱动程序没有executeSql方法。另外,您平均谈论了多少条记录?我不好,看起来executeSql包装了标准节点oracledb查询函数。这是内部的。我认为300-500条记录需要处理。