probleme rowcount avec Forall
Bonjour,
Je suis en 10g et j'utilise le pl/sql.
J'utilise un bulk avec un limite 200 pour un de mes programmes de mises à jours. J'ai environ 300000 enregistrement à traiter.
suite à mon bulk dans des tableaux, j'utilise forall pour faire un update. Juste après, j'utilise sql%rowcount pour savoir si je fais un certain traitement qui doit se faire toute les 2000 enregistrements... mais voilà que le rowcount semble échappé des transactions à certain moment. c'est à dire qu'apres plusieurs milliers de record je remarque que le sql%rowcount me retourne 199 au lieu de 200... cela arrive à plusieurs reprise durant le traitement donc à la fin c'est comme si j'avais un décalage de 50 enregistrements...
Le probleme semble aléatoire d'une fois à l'autre... alors je ne sais plus quoi penser... est-ce un problème connu? est-ce que vous voyez une alternative?
merci
Cause de perte d'enregistrements !
Citation:
Envoyé par
juin29
Bonjour,
Je suis en 10g et j'utilise le pl/sql.
J'utilise un bulk avec un limite 200 pour un de mes programmes de mises à jours. J'ai environ 300000 enregistrement à traiter.
suite à mon bulk dans des tableaux, j'utilise forall pour faire un update. Juste après, j'utilise sql%rowcount pour savoir si je fais un certain traitement qui doit se faire toute les 2000 enregistrements... mais voilà que le rowcount semble échappé des transactions à certain moment. c'est à dire qu'apres plusieurs milliers de record je remarque que le sql%rowcount me retourne 199 au lieu de 200... cela arrive à plusieurs reprise durant le traitement donc à la fin c'est comme si j'avais un décalage de 50 enregistrements...
Le probleme semble aléatoire d'une fois à l'autre... alors je ne sais plus quoi penser... est-ce un problème connu? est-ce que vous voyez une alternative?
merci
Le problème est probablement dû au fait que vous utilisez cursor%notfound pour sortir de votre boucle, ce qui engendrerait la perte d’enregistrements non traités.
Voici un exemple simple montrant pourquoi des enregistrements échappent au traitement :
Code:
1 2
|
create table test_table (col1 number, col2 varchar2(20)); |
Alimenter la table juste pour notre test :
Code:
1 2 3 4 5 6 7 8 9
|
begin
for i in 1..17
loop
insert into test_table (col1, col2)
values (i, 'ligne '||i);
end loop;
commit;
end; |
Maintenant essayons de voir pourquoi des enregistrements ne sont pas traités :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
declare
type num_tab is table of number index by pls_integer;
n_t num_tab;
cursor c
is
select TT.COL1
from test_table tt;
begin
open c;
loop
fetch c bulk collect into n_t limit 10;
exit when c%notfound;
--exit when n_t.count = 0;
for i in 1..n_t.count
loop
dbms_output.put_line(n_t(i));
end loop;
end loop;
close c;
end; |
1er cas : Condition de sortie : exit when c%notfound;
1
2
3
4
5
6
7
8
9
10
Nous remarquons que les sept derniers enregistrements ne sont pas traités.
A la deuxième itération, il y’a sortie de la boucle, il n’a pas d’enregistrement 18ème, les 10 enregistrements suivants ne sont donc pas traités.
2ème cas : Condition de sortie : exit when n_t.count=0;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Nous remarquons que la totalité des enregistrements est traitée.