2019/04/25更新:
バージョン2.2以降、ドライバーにはバッチSQL実行のサポートが組み込まれています。 connection.executeMany()
を使用します 可能であればこれのために。複雑さを軽減しながら、すべてのパフォーマンス上の利点を提供します。詳細については、ドキュメントの「バッチステートメントの実行」セクションを参照してください。 https: //oracle.github.io/node-oracledb/doc/api.html#batchexecution
前の回答:
現在、ドライバはPL / SQLでの配列バインドのみをサポートしており、直接SQLはサポートしていません。将来的にはこれを改善したいと考えています。今のところ、次のことができます...
この表を考えると:
create table things (
id number not null,
name varchar2(50) not null
)
/
以下が機能するはずです:
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.');
}
);
});
これにより、データベースへの1回のラウンドトリップで500行が挿入されます。さらに、DB内のSQLエンジンとPL/SQLエンジン間の単一のコンテキストスイッチ。
ご覧のとおり、配列は個別にバインドする必要があります(オブジェクトの配列をバインドすることはできません)。そのため、この例では、バインドのためにそれらを別々の配列に分割する方法を示しています。これはすべて時間の経過とともによりエレガントになるはずですが、これは今のところ機能します。