Je peux vous assurer que ces actions ne peuvent pas être effectuées en db.
En fait, il existe de nombreuses façons de procéder dans la base de données via SQL et PL/SQL si nécessaire. Les gens veulent souvent utiliser le langage avec lequel ils sont à l'aise, peut-être JavaScript dans ce cas, mais les performances seront bien meilleures si les données ne doivent pas circuler entre les niveaux.
Voici un exemple en SQL uniquement ... Certes, cela aurait pu être fait via des colonnes virtuelles, mais cela devrait illustrer le point.
Imaginez que nous avons les tableaux suivants:
create table things (
id number not null,
val1 number not null,
val2 number not null,
constraint things_pk primary key (id)
);
insert into things (id, val1, val2) values (1, 1, 2);
insert into things (id, val1, val2) values (2, 2, 2);
insert into things (id, val1, val2) values (3, 5, 5);
-- Will hold the sum of things val1 and val2
create table thing_sums (
thing_id number,
sum number
);
alter table thing_sums
add constraint thing_sums_fk1
foreign key (thing_id)
references things (id);
Maintenant, la façon de le faire le plus simple et plus performant que ce serait via SQL:
insert into thing_sums (
thing_id,
sum
)
select id,
val1 + val2
from things
where id not in (
select thing_id
from thing_sums
);
Voici un autre exemple qui fait la même chose que via PL/SQL qui peut fournir plus de contrôle.
begin
-- This cursor for loop will bulk collect (reduces context switching between
-- SQL and PL/SQL engines) implictly.
for thing_rec in (
select *
from things
where id not in(
select thing_id
from thing_sums
)
)
loop
-- Logic in this loop could be endlessly complex. I'm inserting the values
-- within the loop but this logic could be modified to store data in arrays
-- and then insert with forall (another bulk operation) after the loop.
insert into thing_sums(
thing_id,
sum
) values (
thing_rec.id,
thing_rec.val1 + thing_rec.val2
);
end loop;
end;
L'un ou l'autre de ces éléments peut être appelé à partir du pilote Node.js. Cependant, disons que vous devez le faire depuis le pilote (peut-être que vous êtes en train d'intégrer des données qui ne sont pas déjà dans la base de données). Voici un exemple montrant l'appel PL/SQL à partir du pilote qui utilise le traitement en bloc plutôt que des opérations ligne par ligne. C'est beaucoup plus rapide en raison des allers-retours réduits.
J'ai tiré ce d'un billet de blog je travaille donc la définition de la table est un peu différent:
create table things (
id number not null,
name varchar2(50),
constraint things_pk primary key (id)
);
Et voici le JavaScript:
var oracledb = require('oracledb');
var async = require('async');
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;
}
things = getThings(500);
oracledb.getConnection(config, function(err, conn) {
var ids = [];
var names = [];
var start = Date.now();
if (err) {throw err;}
// We need to break up the array of JavaScript objects into arrays that
// work with node-oracledb bindings.
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.');
}
);
});
J'espère que ça aide! :)
Quelles sont les "actions avec une rangée" qui doivent être effectuées? En général, si vous pouvez le faire dans la base de données, plutôt que de récupérer des millions de lignes sur un client ou un serveur d'application, vous serez bien mieux ... – BobC
Je peux vous assurer que ces actions ne peuvent pas être effectuées en db . Par exemple, il y a une sorte de logique qui prend un rang à partir de db, fait des calculs et me donne ensuite un nombre. Et ce numéro je voudrais insérer (ou mettre à jour) dans une autre table. – alingo
Prendre un rang, faire des calculs et obtenir un nombre sonne exactement le genre de chose qu'une base de données est très bonne! – BobC