sql >> Databasteknik >  >> RDS >> Oracle

Hur man infogar flera poster i Oracle DB med Node.js

Uppdatering 2019/04/25:

Drivrutinen, sedan version 2.2, har inbyggt stöd för batch SQL-exekvering. Använd connection.executeMany() för detta när det är möjligt. Den erbjuder alla prestandafördelar med mindre komplexitet. Se avsnittet Utför batchuttalande i dokumentationen för mer information:https://oracle.github.io/node-oracledb/doc/api.html#batchexecution

Tidigare svar:

För närvarande stöder drivrutinen endast arraybindningar med PL/SQL, inte direkt SQL. Vi hoppas kunna förbättra detta i framtiden. För närvarande kan du göra följande...

Med tanke på denna tabell:

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

Följande bör fungera:

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.');
    }
  );
});

Det kommer att infoga 500 rader med en enda tur och retur till databasen. Plus, en enda kontextväxling mellan SQL- och PL/SQL-motorerna i DB.

Som du kan se måste arrayerna bindas in separat (du kan inte binda en array av objekt). Det är därför exemplet visar hur man delar upp dem i separata arrayer för bindningsändamål. Allt detta borde bli mer elegant med tiden, men det här fungerar för tillfället.



  1. PostgreSQL - välj count(*) för rader där ett villkor gäller

  2. Problem med att ansluta Pentaho Kettle/Spoon till Heroku PostgreSQL med SSL

  3. Spring Boot App kan inte komma åt PostgreSQL med hjälp av inloggningsuppgifter från Kubernetes hemlighet

  4. SQL Server infoga om det inte finns bästa praxis