Oracle
 sql >> Datenbank >  >> RDS >> Oracle

So fügen Sie mit Node.js mehrere Datensätze in Oracle DB ein

Aktualisierung vom 25.04.2019:

Der Treiber hat seit Version 2.2 eine integrierte Unterstützung für die Batch-SQL-Ausführung. Verwenden Sie connection.executeMany() dafür ggf. Es bietet alle Leistungsvorteile bei geringerer Komplexität. Weitere Einzelheiten finden Sie im Abschnitt Batch Statement Execute der Dokumentation:https://oracle.github.io/node-oracledb/doc/api.html#batchexecution

Vorherige Antwort:

Derzeit unterstützt der Treiber nur Array-Bindungen mit PL/SQL, nicht direktes SQL. Wir hoffen, dies in Zukunft zu verbessern. Im Moment können Sie Folgendes tun...

Angesichts dieser Tabelle:

create table things (
  id   number not null,
  name varchar2(50) not null
)
/

Folgendes sollte funktionieren:

var oracledb = require('oracledb');
var config = require('./dbconfig');
var things = [];
var idx;

function getThings(count) {
  var things = [];

  for (idx = 0; idx < count; idx += 1) {
    things[idx] = {
      id: idx,
      name: "Thing number " + idx
    };
  }

  return things;
}

// Imagine the 'things' were fetched via a REST call or from a file.
// We end up with an array of things we want to insert.
things = getThings(500);

oracledb.getConnection(config, function(err, conn) {
  var ids = [];
  var names = [];
  var start = Date.now();

  if (err) {throw err;}

  for (idx = 0; idx < things.length; idx += 1) {
    ids.push(things[idx].id);
    names.push(things[idx].name);
  }

  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_ids   number_aat := :ids;
        l_names varchar2_aat := :names;
      begin
        forall x in l_ids.first .. l_ids.last
          insert into things (id, name) values (l_ids(x), l_names(x));
      end;`,
    {
      ids: {
        type: oracledb.NUMBER,
        dir: oracledb.BIND_IN,
        val: ids
      }, 
      names: {
        type: oracledb.STRING,
        dir: oracledb.BIND_IN,
        val: names
      }
    },
    {
      autoCommit: true
    },
    function(err) {
      if (err) {console.log(err); return;}

      console.log('Success. Inserted ' + things.length + ' rows in ' + (Date.now() - start) + ' ms.');
    }
  );
});

Dadurch werden 500 Zeilen mit einem einzigen Roundtrip in die Datenbank eingefügt. Außerdem ein einziger Kontextwechsel zwischen den SQL- und PL/SQL-Engines in der DB.

Wie Sie sehen können, müssen die Arrays separat eingebunden werden (Sie können kein Array von Objekten binden). Aus diesem Grund zeigt das Beispiel, wie Sie sie zu Bindungszwecken in separate Arrays aufteilen. Das sollte alles mit der Zeit eleganter werden, aber im Moment funktioniert es.