问题
I am able to insert one record into a table, but i want to insert multiple records at once into the table-
My Code is below-
var doinsert_autocommit = function (conn, cb) {
var query="INSERT INTO test VALUES (:id,:name)";
var values=[{1,'rate'},{5,'ratee'}];
If i use [1,'rat']- its working for inserting one row.
conn.execute(
"INSERT INTO test VALUES (:id,:name)",
values, // Bind values
{ autoCommit: true}, // Override the default non-autocommit behavior
function(err, result)
{
if (err) {
return cb(err, conn);
} else {
console.log("Rows inserted: " + result.rowsAffected); // 1
return cb(null, conn);
}
});
};
回答1:
Update 2019/04/25:
The driver, since version 2.2, has built-in support for batch SQL execution. Use connection.executeMany()
for this when possible. It offers all of the performance benefits with less complexity. See the Batch Statement Execute section of the documentation for more details: https://oracle.github.io/node-oracledb/doc/api.html#batchexecution
Previous answer:
Currently, the driver only supports array binds with PL/SQL, not direct SQL. We hope to improve this in the future. For now, you can do the following...
Given this table:
create table things (
id number not null,
name varchar2(50) not null
)
/
The following should work:
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.');
}
);
});
That will insert 500 rows with a single roundtrip to the database. Plus, a single context switch between the SQL and PL/SQL engines in the DB.
As you can see, the arrays have to be bound in separately (you can't bind an array of objects). That's why the example demonstrates how to break them up into separate arrays for binding purposes. This should all get more elegant over time, but this works for now.
回答2:
Checkout the executeMany() method introduced in node-oracledb 2.2. This executes one statement with many data value, generally with significant performance benefit over calling execute()
many times.
回答3:
I used the simple-oracledb library for batch insert, its extending the oracledb module.
var async = require('async');
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
var SimpleOracleDB = require('simple-oracledb');
SimpleOracleDB.extend(oracledb);
var doconnect = function(cb) {
oracledb.getConnection(
{
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
},
cb);
};
var dorelease = function(conn) {
conn.close(function (err) {
if (err)
console.error(err.message);
});
};
var doinsert_autocommit = function (conn, cb) {
conn.batchInsert(
"INSERT INTO test VALUES (:id,:name)",
[{id:1,name:'nayan'},{id:2,name:'chaan'},{id:3,name:'man'}], // Bind values
{ autoCommit: true}, // Override the default non-autocommit behavior
function(err, result)
{
if (err) {
return cb(err, conn);
} else {
console.log("Rows inserted: " + result.rowsAffected); // 1
return cb(null, conn);
}
});
};
async.waterfall(
[
doconnect,
doinsert_autocommit,
],
function (err, conn) {
if (err) { console.error("In waterfall error cb: ==>", err, "<=="); }
if (conn)
dorelease(conn);
});
来源:https://stackoverflow.com/questions/45569126/how-to-insert-multiple-records-into-oracle-db-using-node-js