|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Bonjour à tous,
J'ai un programme (C++) qui réalise des requêtes UPDATE cycliquement sur une table. Le problème, c'est que je ne dois pas effectuer la mise à jour de l'enregistrement si la valeur du champ NOM_DU_CHAMP est inchangée. Juste avant d'effectuer la requête UPDATE, j'effectue un SELECT pour récupérer l’enregistrement existant, et je n'effectue l'UPDATE uniquement si la valeur de NOM_DU_CHAMP est différente. Ne serait-il pas mieux d'effectuer les UPDATE dans mon programme C++ sans me poser de question, et d'ajouter un TRIGGER BEFORE UPDATE à ma table qui annulerait l'UPDATE si nécessaire. Quelle solution vous semble la plus judicieuse? Si c'est celle du Trigger, comment annuler l'UPDATE si l'ancienne et la nouvelle valeur du champ sont identique? Merci d'avance pour vos conseils. PS: A noter qu'il y a plus d'UPDATE annulé qu'effectué.
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
|
|
#2 | ||
|
Membre du Club
![]() Arnaud Inscription : octobre 2002 Messages : 56 ![]() |
Bonjour,
Pourquoi ne pas inclure le test dans ton update, cela éviterait de perdre du temps à récupérer la valeur d'abord et cela me semble plus "naturel" (enfin bon c'est personnel Code :
[Edit] Je pense que c'est plus judicieux de faire comme cela car: - Pas de logique superflue dans ton code - Pas de trigger, j'évite au maximum d'en utiliser car je trouve que leur coût en terme de maintenance est souvent élevé (tout le monde les oublie, et on perd a chaque fois du temps à chercher à droite a gauche l'origine d'un problème, avant de penser aux triggers) - Je pense qu'un update réalisé comme cela est globalement moins coûteux qu'un select systématique ou un trigger systématique pour vérifier les valeurs. Je n'ai pas vérifié ce point.
__________________
Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design. |
||
|
|
20
|
|
|
#3 | ||
![]() ![]() |
Attention à ne pas oublier les nulls (ce n'est pas précisé, donc c'est peut-être inutile) :
Code :
__________________
Email : http://scr.im/waldar |
||
|
10
|
|
|
#4 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Merci, je vais voir pour adapter mon code en ce sens...
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
|
|
#5 | |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Citation:
Pensez aussi à l'appel de cette procédure. Il faudrait que vous l'appelliez en utilisant des ''binds variables'' si elle contient des paramètres. Pour cela vous devez utilisez OCI interface OCIStmtPrepare2 et OCIDefineByPos. Je ne suis pas un spécialiste de ce qui précède mais vous pouvez trouvez des détails sur ceci dans le livre de Chistian Antognini: http://www.amazon.fr/Troubleshooting-Oracle-Performance-Christian-Antognini/dp/1590599179 Si vous ne le faites pas correctement vous allez remplir la mémoire (v$sql) de vos appels à la procédure. http://hourim.wordpress.com/2011/06/...ing-parameter/ |
|
|
|
00
|
|
|
#6 |
|
Membre du Club
![]() Arnaud Inscription : octobre 2002 Messages : 56 ![]() |
Utiliser des bind variable est une bonne pratique, mais ce n'est pas toujours possible (Risque de régression dans une appli existante, pas le temps, ou choix projet: "nan, on veut pas appeler de procédure et pis c'est tout").
Dans ce cas, il y a aussi le paramètre CURSOR_SHARING, qui peut être intéressant il me semble. Mais s'il n'y a pas de problème de performance relatif à ces updates, je ne sais pas si sat83 à besoin de se poser ces questions
__________________
Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design. |
|
|
00
|
|
|
#7 |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
[QUOTE=Dans ce cas, il y a aussi le paramètre CURSOR_SHARING, qui peut être intéressant il me semble.
QUOTE] Dans ce cas je pense que vous n'avez pas lu le lien que j'ai proposé. |
|
|
00
|
|
|
#8 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
|
|
|
00
|
|
|
#9 |
|
Membre du Club
![]() Arnaud Inscription : octobre 2002 Messages : 56 ![]() |
@Mohamed: Oui, j’avoue, je n'ai pas pris le temps de lire votre article dans le détail
__________________
Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design. |
|
|
00
|
|
|
#10 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
En faite j'utilise effectivement un MERGE.
Si l'enregistrement existe j'effectue un UPDATE, et si il n'existe pas encore j'effectue un INSERT. Maintenant je souhaiterais ajouter la nuance: si l'enregistrement existe et que 3 champs sont identiques, je ne fais rien. J'aurais pensé utiliser une clause WHERE dans le UPDATE du MERGE, mais apparemment ce n'est pas possible. J'avou ne pas être trop à l'aise avec le MERGE. Est ce que ca vous semble possible comme fonctionnement avec un MERGE de faire soit un INSERT, soit un UPDATE, soit RIEN?
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
|
|
#11 | |
![]() ![]() |
Citation:
Mettez votre clause WHERE avant la clause WHEN NOT MATCHED THEN INSERT.
__________________
Email : http://scr.im/waldar |
|
|
00
|
|
|
#12 | ||
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Malheureusement ça ne fonctionne pas...
Mon MERGE fonctionne bien, mais j'ai une erreur lorsque j'ajoute une clause WHERE dans l'UPDATE: Code :
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
||
|
|
00
|
|
|
#13 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Quelle version d'oracle ?
merge enhancements in 10g |
|
|
10
|
|
|
#14 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
ORACLE 9.i
Je pense que ça doit venir de là... Ca ne doit fonctionner qu'avec la version 10. Je pense que dans mon programme C++ je vais remplacer mon MERGE par un SELECT suivi d'un INSERT, d'un UPDATE ou de RIEN selon le cas...
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
|
|
#15 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
|
|
|
00
|
|
|
#16 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Je pensais que si je ne sélectionnais pas ces enregistrements, la requête MERGE effectuerait un INSERT, non?
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
|
|
#17 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Pour un ensemble des enregistrements sélectionnés le merge fait soit insert soit update. Si parmi ces enregistrements ne figure pas celles qui existent déjà dans la table à mettre à jour et qui respectent certaines critères alors il n’y aurait pas de problème.
|
|
|
00
|
|
|
#18 | ||
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Voici une version simplifiée de ma requête MERGE:
Code :
J'aimerais que si l'enregistrement existe ET si les 3 champs (6 à 8 par exmeple) son identiques à ceux existant ALORS je ne fais RIEN (ni INSERT ni UPDATE) Merci d'avance pour vos éclaircissement!
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
||
|
|
00
|
|
|
#19 | ||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Vous pouvez ajouter une clause where à votre update comme dans l'exemple ci-dessous
Code :
|
||
|
|
00
|
|
|
#20 |
|
Membre Expert
![]() Développeur informatique Inscription : mars 2004 Messages : 978 ![]() |
Malheureusement, comme expliqué plus haut, la clause WHERE ne fonctionne pas dans un MERGE sous ORACLE 9.i
__________________
Ce que l'on apprend par l'effort reste toujours ancré plus longtemps... |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com