IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

Cohérence de données et commit


Sujet :

Oracle

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Décembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Cohérence de données et commit
    Bonjour,

    J'ai un problème de cohérence de données et je ne sais pas si il peut être résolu avec un select for update et si oui les modifications à faire

    Voici mon code posant problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    FOR unites_operationnelles in ( SELECT distinct org_id
                                               FROM xxbp_prov_factures_annulees
    	                                   WHERE code_annulation in ('AT')
    	                                 )
               LOOP
     
                   XXBP_AP_PROVISIONS_PKG.connection_oa_p(unites_operationnelles.org_id);
     
                   FOR factures in ( SELECT set_of_books_id,
                                            invoice_id,
                                            period_name,
                                            check_id
                                     FROM xxbp_prov_factures_annulees
                                     WHERE org_id = unites_operationnelles.org_id
                                       AND code_annulation in ('AT')
                                   )
                   LOOP
     
                       BEGIN
                            v_result_annulation := AP_CANCEL_PKG.ap_cancel_single_invoice
                                                                   ( P_invoice_id                 => factures.invoice_id,
    	       	                                                 P_last_updated_by            => 0,
    	       	      					         P_last_update_login          => 0,
    	       	   					    	 P_set_of_books_id            => factures.set_of_books_id,
    	       	   					    	 P_accounting_date            => TRUNC(sysdate),
    	       	   					    	 P_period_name                => factures.period_name,
    	       	   					    	 P_message_name               => v_message_name,
    	       	   					    	 P_invoice_amount             => v_invoice_amount,
    	       	   					    	 P_base_amount                => v_base_amount,
    	       	   					    	 P_tax_amount                 => v_tax_amount,
    	       	   					    	 P_temp_cancelled_amount      => v_temp_cancelled_amount,
    	       	   					    	 P_cancelled_by               => v_cancelled_by,
    	       	   					    	 P_cancelled_amount           => v_cancelled_amount,
    	       	   					    	 P_cancelled_date             => v_cancelled_date,
    	       	   					    	 P_last_update_date           => v_last_update_date,
    	       	   					    	 P_original_prepayment_amount => v_original_prepayment_amount,
    	       	   					    	 P_check_id                   => factures.check_id,
                                                                     P_pay_curr_invoice_amount    => v_pay_curr_invoice_amount,
    	       	   					    	 P_calling_sequence           => 'APXINWKB'
    	       	   					       );
     
    	                EXCEPTION
    	                    WHEN OTHERS THEN
    	                         v_message_name := SQLCODE||' '||SQLERRM;
     
    	           END;
     
    	           UPDATE xxbp_prov_factures_annulees
    	           SET code_annulation = decode(v_message_name, null, 'OK', 'KO'),
                           message_annulation = v_message_name
                       WHERE invoice_id = factures.invoice_id;
     
                       UPDATE ap_invoice_distributions_all aida
                       SET global_attribute2 = 'Y'
                       WHERE cancellation_flag = 'Y'
                         AND last_updated_by = 0
                         AND invoice_id = factures.invoice_id;
     
     
                       COMMIT;
     
     
                   END LOOP;
     
               END LOOP;
    J'aimerais aussi savoir si les modifications sont prises en compte à chaque ligne ou une fois sortie des boucles.

    Merci d'avance pour vos réponses

  2. #2
    Membre éclairé Avatar de plabrevo
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 547
    Points : 670
    Points
    670
    Par défaut
    Les modifications sont "prises en compte" (lire committees) pour chaque unite_operationnel et chaque facture, puisque un COMMIT figure au mileu de la boucle.

    Maintenant, je ne trouve pas que le datafix soit elegant en raison de la gestion d'exception beaucoup trop tolerante a mon gout, de l'absence de reservation des records lors du fetch, de l'utilisation de deux LOOP imbriquees lorsqu'une suffirait, et d'un COMMIT au milieu de la boucle, generalement a proscrire pour eviter les erreurs snapshot_too_old.

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Décembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    C'est justement cela mon problème. Je souhaite réécrire ce bout de code afin qu'il soit plus propre et ainsi éviter les erreurs de type snapshot too old mais je ne sais pas comment faire

  4. #4
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut Opti
    1/ Vu que tu ne veux faire ton appel à XXBP_AP_PROVISIONS_PKG.connection_oa_p qu'une seule fois par org_id, dans ce cas 1 seul curseur trié par org_id.
    Si ce champ est NOT NULL, le code ci dessous est correct, sinon faut rajouter une variable v_premier_enreg que tu mets à jour la première fois.

    2/ Un CURRENT OF plutôt que invoice_id = factures.invoice_id;, je pense qu'il prend le rowid plutôt que l'index je pense que c'est mieux.

    3/ j'ai sorti le COMMIT de la boucle pour éviter les SNAPSHOT TOO OLD

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    v_orgid := NULL;
     
    FOR factures IN ( SELECT org_id, set_of_books_id, invoice_id, period_name,  check_id 
                       FROM XXBP_PROV_FACTURES_ANNULEES 
                       WHERE code_annulation = 'AT'
    					ORDER BY org_id
    					FOR UPDATE 
                     ) 
    LOOP 
     
    -- Si on est sur un nouvel org_id ou le premier 
     IF v_orgid <> factures.org_id OR v_orgid = NULL
     THEN
    	v_orgid := factures.org_id;
    	 XXBP_AP_PROVISIONS_PKG.connection_oa_p(v_orgid); 
     END IF;
     
     
      BEGIN 
           v_result_annulation := AP_CANCEL_PKG.ap_cancel_single_invoice 
                          (  P_invoice_id                 => factures.invoice_id, 
                             P_last_updated_by            => 0, 
                             P_last_update_login          => 0, 
                             P_set_of_books_id            => factures.set_of_books_id, 
                             P_accounting_date            => TRUNC(SYSDATE), 
                             P_period_name                => factures.period_name, 
                             P_message_name               => v_message_name, 
                             P_invoice_amount             => v_invoice_amount, 
                             P_base_amount                => v_base_amount, 
                             P_tax_amount                 => v_tax_amount, 
                             P_temp_cancelled_amount      => v_temp_cancelled_amount, 
                             P_cancelled_by               => v_cancelled_by, 
                             P_cancelled_amount           => v_cancelled_amount, 
                             P_cancelled_date             => v_cancelled_date, 
                             P_last_update_date           => v_last_update_date, 
                             P_original_prepayment_amount => v_original_prepayment_amount, 
                             P_check_id                   => factures.check_id, 
                             P_pay_curr_invoice_amount    => v_pay_curr_invoice_amount, 
                             P_calling_sequence           => 'APXINWKB' 
                            ); 
      EXCEPTION 
      WHEN OTHERS THEN 
                 v_message_name := SQLCODE||' '||SQLERRM; 
      END; 
     
      UPDATE XXBP_PROV_FACTURES_ANNULEES 
      SET code_annulation = DECODE(v_message_name, NULL, 'OK', 'KO'), 
          message_annulation = v_message_name 
    -- Si invoice_id est bien unique.
      WHERE CURRENT OF factures;
    -- WHERE invoice_id = factures.invoice_id; 
     
    	UPDATE AP_INVOICE_DISTRIBUTIONS_ALL AIDA 
    	SET global_attribute2 = 'Y' 
    	WHERE cancellation_flag = 'Y' 
    	AND last_updated_by = 0 
    	AND invoice_id = factures.invoice_id; 
     
    	END LOOP; 
     
    	COMMIT;

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Décembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok je vais essayer.
    Merci

Discussions similaires

  1. Lier, modifier et cohérence des données issues de deux tables
    Par lawappe dans le forum Bases de données
    Réponses: 33
    Dernier message: 20/03/2009, 17h11
  2. Réponses: 3
    Dernier message: 08/10/2008, 16h34
  3. Problème de cohérence de données lors de suppression d'une ligne
    Par Alphadjo dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 30/06/2008, 20h07
  4. Réponses: 13
    Dernier message: 28/07/2005, 13h11
  5. Réponses: 2
    Dernier message: 18/12/2002, 10h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo