|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Membre à l'essai
![]() Inscription : mars 2004 Messages : 122 ![]() |
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 |
|
|
00
|
|
|
#2 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
|
|
|
00
|
|
|
#3 |
|
Membre à l'essai
![]() Inscription : mars 2004 Messages : 122 ![]() |
ce que je comprend c'est que tu me dis d'utiliser le SQL%BULK_ROWCOUNT(i). Mais comme le I fait référence au counteur du bulk et bien ce n'est pas vraiment mon besoin... j'ai besoin de savoir combien d'enregistrement ont été updater avec mon FORALL update... en principe, il devrait y en avoir 200 jusqu'avant la fin à moins que les condition du update ne soit pas répondu... mais comme le where clause est le meme que celui du select de mon bulk... je ne vois pas pourquoi il en sauterais...
est-ce que je comprends bien ce que tu souhaitait m'expliquer... je ne suis pas sur que ce soit ca que j'ai besoin à moins que je ne comprenne pas bien comment ca fonctionne. merci |
|
|
00
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Oui c'est ça. Maintenant ça pourrait aller mieux avec un petit exemple.
Si je comprends bien, votre problème est que des enregistrements semble disparaitre du traitement. Cella pourrait s'expliquer si des autres transactions modifient en même temps les données utilisées par votre traitement: 1) Vous chargez 200 lignes qui correspondent à vos critères dans un tableau sans les verrouiller. 2) Une autre transaction commit une modification pour une de colonnes utilisées comme critère de sélection d'une de vos lignes. 3) Vous faite l'update avec les mêmes critères que le select mais maintenant la ligne n'a plus la valeur de début dans la base. |
|
|
00
|
|
|
#5 |
|
Membre à l'essai
![]() Inscription : mars 2004 Messages : 122 ![]() |
ca aurait tres bien pu etre ca... mais c'est un environnement de dev dont je suis le seul utilisateur... donc... je ne comprend pas trop...
par contre... le sql%ROWCOUNT utilisé apres un update... retourne bien le nombre d'update effectué? donc si dans une boucle donnée l'update correspondant au where-clause correspond seulement à 199 sur 200, le sql%rowcount devrait me retourné 199 au lieu du 200 attendu pour cette fois là n'est-ce pas ? Si on fait un parrallele avec le SQL%BULK_ROWCOUNT(i)... ne devrait-il pas toujours me retourné 200 puisque la limite du bulk est 200? si oui, ca n'a aucun rapport avec l'update je me trompe? |
|
|
00
|
|
|
#6 | ||
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Le SQL%ROWCOUNT ne peut être utilisé qu’après l’instruction FORALL. Il vous donne le nombre total, cumulative des enregistrements modifié par le FORALL. Voilà un exemple:
Code :
|
||
|
|
00
|
|
|
#7 | ||
|
Membre éclairé
![]() Inscription : novembre 2002 Messages : 532 ![]() |
Bonjour
Ajoute un save exceptions à ton forall Exemple : Code :
__________________
PpPool |
||
|
|
00
|
|
|
#8 | |||||||
|
Invité régulier
![]() |
Citation:
Voici un exemple simple montrant pourquoi des enregistrements échappent au traitement : Code :
Code :
Code :
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. |
|||||||
|
|
20
|
|
|
#9 | |||
![]() Inscription : décembre 2002 Messages : 2 385 ![]() |
Citation:
Néanmoins, ce n'est pas tant le %NOTFOUND en soi qui est un problème, c'est surtout une question de localisation. Si on le met après la portion de code qui traite le lot de lignes ramenées, et non juste après le FETCH, ça peut marcher même quand le lot de lignes n'est pas complet (inférieur à n). Code :
Votre test de sortie sur le COUNT de la collection étant simple et universel, il n'y a pas de raison de s'en priver ! D'ailleurs, il est amusant de voir que Feuerstein pousse le bouchon encore plus loin en recommandant carrément, si j'ai bien compris, de ne plus utiliser le test avec %NOTFOUND dès lors qu'on utilise du BULK COLLECT, et ce avec ou sans LIMIT. http://www.oracle.com/technetwork/is...ql-095155.html
__________________
Consultant / formateur Oracle indépendant Certifié OCP 10g et 11g, sécurité 11g |
|||
|
|
10
|
Copyright © 2000-2012 - www.developpez.com