Procédure d'update et rowid
Hello tout le monde,
Parfois, lorsque j'ai un update assez volumineux à faire, j'utilise un truc du style:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| declare
cursor cur
is
select key1, key2
from my_table
where key1 = 'toto';
type my_record is record (
key1 my_table.key1%type,
key2 my_table.key2%type
);
type my_data is table of my_record
index by binary_integer;
my_key my_data;
number_rows number := 0;
begin
open my_cur;
loop
fetch my_cur
bulk collect into my_key limit 20000;
if my_key.count > 0
then
for my_row in 1 .. my_key.count loop
update my_table
set data1 = data1+data2
where key1 = my_key (my_row).key1
and key2 = my_key (my_row).key2;
commit;
end loop;
else
exit;
end if;
end loop;
close my_cur;
commit;
exception
when others
then
if my_cur%isopen
then
close my_cur;
end if;
end; |
Pour faire simple, je fait un curseur sur les colonnes de ma clé primaire, et je parcours la table par lot de 20000 lignes de ce curseur.
Et aujourd'hui, je me suis demandé pourquoi ne pas plutôt utiliser un rowid à la place... ça éviterait d'avoir une table de record, et ça serait peut-être plus simple ?
Ma question est donc toute bête : est-ce que quelque chose m'empêcherait de faire le même genre de requête en utilisant le rowid à la place des 2 colonnes de ma clé ?
Question subsidiaire (parce que sur certaines base, je n'ai visiblement pas de rowid): c'est apparu sur une version récente ce rowid ? Ou est-ce qu'il faut l'activer d'une manière ou d'une autre ?
Merci d'avance :)
Jacky-tunning dans la place
Le mieux ce serait d'utiliser un FORALL :D
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
LOOP FETCH MY_CUR BULK COLLECT INTO MY_KEY LIMIT 20000;
IF MY_KEY.COUNT > 0 THEN
-- FOR my_row IN 1 .. my_key.count loop
-- UPDATE my_table
-- SET data1 = data1+data2
-- WHERE key1 = my_key (my_row).key1
-- AND key2 = my_key (my_row).key2;
FORALL I IN MY_KEY.FIRST .. MY_KEY.LAST
UPDATE MY_TABLE SET DATA1 = DATA1 + DATA2
WHERE KEY1 = MY_KEY(I).KEY1 AND KEY2 = MY_KEY(I).KEY2;
COMMIT;
ELSE .... |
De cette maniere, au lieu de faire les mises-a-jour une par une, il fait des paquets de 20 000. Ca devrait aller plus vite.
Bon par contre, c'etait pas la question.;)