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

PL/SQL Oracle Discussion :

Proc stock : update et variables pas toutes enregistrées


Sujet :

PL/SQL Oracle

  1. #1
    Membre confirmé
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2009
    Messages
    339
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 339
    Points : 586
    Points
    586
    Par défaut Proc stock : update et variables pas toutes enregistrées
    Bonjour,

    j'ai un petit soucis avec une procédure stockée dans laquelle j'aimerais mettre à jour 3 champs d'un enregistrement.
    Malheureusement, après déclenchement, un seul des trois champs est mis à jour.
    Est-ce que j'aurais oublié quelque chose ? Problème de syntaxe ? D'initialisation ?

    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
    create or replace
    PROCEDURE TEST
    (
      ARG_REFERENCE_ACC IN VARCHAR2 DEFAULT NULL,
      ARG_KVPS_ISAC IN VARCHAR2 DEFAULT NULL
    
    )
    AS
    
      mo_forfait NUMBER(6,2);
      mo_taux NUMBER(6,2);
      pose_ht NUMBER(6,2);
      
      pricing_accessoire GVF_ACCESSOIRES_PRICING%ROWTYPE;
      pricing_produit GVF_ACCESSOIRES_PRICING%ROWTYPE;
      pricing_sousfamille GVF_ACCESSOIRES_PRICING%ROWTYPE;
      pricing_famille GVF_ACCESSOIRES_PRICING%ROWTYPE;
    
    BEGIN
    
      mo_forfait := 0;
      mo_taux := 0;
      pose_ht := 0;
    
      -- obtenir l'enregistrement pricing de l'accessoire
      SELECT * INTO pricing_accessoire FROM GVF_ACCESSOIRES_PRICING
        WHERE GVF = '0' AND KVPS_ISAC = ARG_KVPS_ISAC
        AND REFERENCE_ACCESSOIRE = ARG_REFERENCE_ACC;
        
          mo_forfait := 9;
          mo_taux := 9;
          
          pose_ht := mo_forfait + mo_taux +1;
    
          --mise à jour de l'enregistrement du pricing accessoire avec la MO
          UPDATE GVF_ACCESSOIRES_PRICING
            SET MO_FORFAIT = mo_forfait,
                MO_TAUX = mo_taux,
                POSE_PRIX_HT_UNITAIRE = pose_ht
            WHERE GUID = pricing_accessoire.GUID;
    
    
    
    END TEST;
    Dans l'enregistrement mis à jour, seul le champ POSE_PRIX_HT_UNITAIRE est actualisé.

    Toute aide même minime est la bienvenue.
    D'avance merci

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    Vous avez fait une belle erreur, en nommant vos variables comme les colonnes, regardez votre update au final :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     UPDATE GVF_ACCESSOIRES_PRICING
        SET MO_FORFAIT = mo_forfait,
            MO_TAUX = mo_taux
    Oracle fait bien ce que vous lui demandez, il remet la même valeur dans la même colonne.

    Utilisez des règles de nommages pour vos objets PL/SQL, préfixez les variables par v$_ et les paramètres par p$_ par exemple.

  3. #3
    Membre confirmé
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2009
    Messages
    339
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 339
    Points : 586
    Points
    586
    Par défaut
    Effectivement... J'étais passée à côté de ce "petit détail"...
    ça marche bien mieux, merci beaucoup.

  4. #4
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Waldar Voir le message
    ...Utilisez des règles de nommages pour vos objets PL/SQL, préfixez les variables par v$_ et les paramètres par p$_ par exemple.
    Et n’oubliez pas de proscrire ces règles de nommage pour colonnes des tables.
    La bonne solution, mais rarement utilisée, est de préfixer le nom des variables avec le nom de la fonction ou du bloc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    create or replace procedure foo
    Is
      empno emp.empno%Type;
    Begin
      update emp
         set ename = 'Toto'
       Where empno = foo.empno;
    End;
    /

  5. #5
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par mnitu Voir le message
    La bonne solution, mais rarement utilisée, est de préfixer le nom des variables avec le nom de la fonction ou du bloc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    create or replace procedure foo
    Is
      empno emp.empno%Type;
    Begin
      update emp
         set ename = 'Toto'
       Where empno = foo.empno;
    End;
    /
    Marius,

    Certains experts(David Aldridge) sont du même avis que vous

    https://forums.oracle.com/forums/thr...65231&#9465231
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  6. #6
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 073
    Points
    8 073
    Par défaut
    Citation Envoyé par Mohamed.Houri Voir le message
    Marius,

    Certains experts(David Aldridge) sont du même avis que vous

    https://forums.oracle.com/forums/thr...65231&#9465231
    Mouais, mais comme il n'a aucun argument convaincant, son avis à autant de poids que s'il disait qu'il aime le vert et pas le rouge.
    Je ne vois franchement pas l'intérêt de surcharger son code en préfixant chaque variable par le nom de la procédure. Les bons vieux préfixes p_ et v_ , qui sont de tradition depuis des lustres, ont le mérite de rester concis tout en assurant la distinction avec le nom des colonnes.
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    ...Les bons vieux préfixes p_ et v_ , qui sont de tradition depuis des lustres, ont le mérite de rester concis tout en assurant la distinction avec le nom des colonnes.
    Bad habits die hard!

    Bryn Llewellyn, PL/SQL Product Manager, Oracle Headquarters,
    Doing SQL From PL/SQL Best And Worst Practices
    Some programmers have become attached to a style where they name local
    variables and formal parameters using a prefix or suffix convention that denotes
    this status. (Some go further and use names that distinguish between in different
    parameter modes — in, out, and in out.) They usually claim that the style
    inoculates against the risk of name capture.
    ...
    The style can work only if a development
    shop insists on a wider naming convention that, for example, bans columns in
    schema-level tables with names starting with p_ or l_. However, the
    PL/SQL compiler cannot trust such a humanly policed rule, and this fact
    becomes more significant in Oracle Database 11g which brings fine grained
    dependency tracking.
    ...
    Principle_1
    When writing an embedded SQL statement, always establish an alias for each
    from list item and always qualify each column with the appropriate alias. Always
    qualify the name of every identifier that you intend the be resolved in the
    current PL/SQL unit with the name of the block in which it is declared. If this
    is a block statement, give it a name using a label. The names of the aliases and
    the PL/SQL bocks must all be different. This inoculates against name capture
    when the referenced tables are changed and, as a consequence, increases the
    likelihood that the fine-grained dependency analysis will conclude that the
    PL/SQL unit need not be invalidated.

  8. #8
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 073
    Points
    8 073
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Bad habits die hard!
    C'est bien vrai ça, les mauvais habits meurent durement !

    Certes, pour que les préfixes p_ et v_ permettent d'éviter la confusion avec les noms de colonnes, aucune colonne ne doit commencer par un tel préfixe : c'est du simple bon sens.
    Je reconnais que rien ne garantit que ce bon sens sera respecté par tous. Ca reste cependant très facile à vérifier, si on y tient, en consultant DBA_TAB_COLUMNS.

    Pour ma part, quand je prends le volant, je ne m'habille pas en combinaison de plongée avec bouteilles d'oxygène, pour le cas où ma voiture viendrait à tomber à l'eau. Pourtant, le risque n'est pas nul, un tel accident fait plusieurs morts chaque année.

    Cette histoire de préfixer chaque variable par le nom du bloc dans laquelle elle a été déclarée est du même ordre que la bouteille d'oxygène ; cela explique probablement pourquoi cette technique, comme tu l'indiques toi-même, est "très peu employée".
    Et je n'ai pas remarqué, jusque là, dans les exemples de code que tu proposes, que tu l'utilisais non plus...
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  9. #9
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Malheureusement j'ai comme l'impression qu'il ne faut pas enrichir ce forum avec des liens que l'on juge pertinents. Sinon, comment expliquer qu'il en reçoit des notes négatives alors qu'à mes yeux il mérite d'être lu et apprécié à sa juste valeur. Que ceux qui le trouvent mal approprié aient au moins le mérite de nous en donner la raison. Cela servira à tout le monde j'en suis persuadé.

    http://jamesmorle.wordpress.com/2011...ight-practice/
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  10. #10
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Avez-vous pris le temps de lire tout le paragraphe en question et de bien noter les changements dans la gestion des dépendances induites par la version 11g ?

    Earlier, dependency information was recorded only with the granularity of the
    whole object.
    In the example in Code_6, it would be recorded just that the
    current PL/SQL unit depends on the table t. Now, in Oracle Database 11g, it is
    recorded that the PL/SQL unit depends on the columns t.v and t.PK within
    table t. The new approach aims to reduce unnecessary invalidation by avoiding it
    when a referenced object is changed in a way which is immaterial for the
    dependant.
    In this example, the beginner might think at first that the addition of
    a new column to t, when the dependant PL/SQL unit refers to only certain
    named columns in t, would be immaterial. But the discussion of name capture
    shows that this is not always the case: the name of the new column might collide
    with what used to be an escaping identifier that was resolved in PL/SQL scope.
    The only way to guarantee that the PL/SQL has the correct meaning in the
    regime of the altered table is to invalidate it in response to the addition of the
    new column so that it will be recompiled and the name resolution will be done
    afresh.
    -- Code_6 Fine_Grained_Dependency_Test.sql
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select v1
    into l_v1
    from t where PK = p_PK;
    Doing SQL from PL/SQL: Best and Worst Practices page 9
    21-September-2008 http://www.oracle.com/technology/tec...from_plsql.pdf
    The use of qualified names, as used in Code_3, changes the analysis. The qualified
    identifier b.PK, cannot possibly mean a column (existing or new) in the table
    whose alias in the query is a. This is easily confirmed by experiment. Create table
    t with columns PK and v, procedure p1 containing Code_3 and procedure p2
    containing Code_6. Confirm, with a User_Objects query, that both are valid. Then
    alter t to add a column (for example c1 of datatype number) and repeat the
    User_Objects query; p1 remains valid but p2 becomes invalid13.

  11. #11
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 073
    Points
    8 073
    Par défaut
    Marius, si tu avais la bonté de traduire (ou au moins résumer) tout ces pavés en français, ça faciliterait la discussion, et ceux qui viennent sur un forum francophone pour avoir la chance de comprendre ce qui s'y dit, se joindraient à moi pour t'en remercier.

    La technique que tu recommandes réduit les risques d'invalidations inutiles. C'est une très bonne chose que ça existe et que tu nous en fasses part.
    Maintenant, selon son contexte, chacun est libre de juger que les invalidations ne lui posent aucun problème, et que le préfixage de toutes les variables est une peine démesurée.

    Je ne peux qu'acquiescer lorsque Morle dit qu'il faut avant tout comprendre l'esprit et la justification d'une "bonne pratique", ce qui permet de l'adopter ou non en connaissance de cause.

    Et non, je n'ai pas lu les 70 pages de ton document, je garde ça pour ma retraite (30 ans, c'est vite passé).
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  12. #12
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    ...
    Et non, je n'ai pas lu les 70 pages de ton document, je garde ça pour ma retraite (30 ans, c'est vite passé).
    Bref, il y a en tout 2 pages à lire sur le sujet que t'as très bien résumé et non pas 70 . Mais, le fait de ne pas les lire te donne toujours le droit de dire:
    "...avant tout comprendre l'esprit et la justification ...".
    Je comprends bien que nous ne sommes pas d'accord mais je m'attendais que t'aller faire l'effort d'abord de parcourir les explications avant de renforcer ton premier avis.

  13. #13
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 073
    Points
    8 073
    Par défaut
    Sur le fond, si je résume bien, ta recommandation (préfixer toute variable par le nom du bloc dans lequel elle a été déclarée) procure 2 avantages :
    - elle améliore la robustesse du code en garantissant qu'il n'y aura jamais de confusion entre une variable et un nom de colonne, même si les noms de colonnes des tables sont amenés à évoluer
    - à partir de la 11g, elle pourra éviter certaines invalidations inutiles d'objets PL/SQL, lorsque des modifications non significatives ont lieu dans les objets référencés.

    J'ai dit ce que je pensais du bénéfice de ces avantages par rapport aux efforts d'écriture du code qu'ils imposent.

    Sur la méthode, je ne considère pas que faire sèchement des copier/coller, sans aucune explication complémentaire, constitue une argumentation, et encore moins une argumentation conviviale ni pédagogique.
    Qui plus est, sur un forum francophone, le principe est de s'exprimer en français.
    Quant à ton lien, il pointe vers une liste de documents dans laquelle il faut choisir le bon, qui fait 79 pages (en anglais encore), et se débrouiller pour deviner quelle partie tu voulais qu'on lise.

    Bref, je ne suis pas convaincu que tes procédés soient en phase avec tes intentions. (Cela dit, je serais heureux de partager une bière avec toi à la première occasion )
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  14. #14
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    Au final, j'aurai appris qu'on peut nommer un bloc PL/SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <<blc>>
    declare
        toto pls_integer;
    begin
        for cur in (select 1 as toto from dual)
        loop
          blc.toto := cur.toto;
        end loop;
        dbms_output.put_line(to_char(blc.toto));
    end blc;
    J'ai toujours préféré les références explicites aux implicites, si je ne le faisais pas en PL/SQL c'était par ignorance.
    Je vais maintenant avoir de quoi faire de la revue de mon propre code !

  15. #15
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    ...Sur la méthode, je ne considère pas que faire sèchement des copier/coller, sans aucune explication complémentaire, constitue une argumentation, et encore moins une argumentation conviviale ni pédagogique.
    ...
    J'avais trouvé cela très bien expliqué et j'avais peur que ma traduction n’appauvrisse pas le paragraphe en question .
    Cela étant dit

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Requête update ne fonctionnant pas tout le temps
    Par feldi dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 30/03/2011, 16h44
  2. variables pas toutes liées dans select imbriqué
    Par mialy.rakot dans le forum SQL
    Réponses: 10
    Dernier message: 17/02/2011, 07h59
  3. Mettre le résultat d'une Proc Stock dans une variable
    Par zooffy dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 18/06/2008, 12h20
  4. [T-SQL]Envoyer en paramètre de proc stock Sybase une variable date shell
    Par Doctor Z dans le forum Adaptive Server Enterprise
    Réponses: 5
    Dernier message: 30/10/2007, 17h18
  5. PB proc stock avec like variable %
    Par pseudomh dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 31/03/2005, 12h49

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