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 :

Comprendre le résultat (NoCopy)


Sujet :

PL/SQL Oracle

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2003
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 109
    Par défaut Comprendre le résultat (NoCopy)
    Salut a tous,

    Jai un algorithme tout simple en PL/Sql que jarrive pas a piger, pouvait vous maider svp?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DECLARE
    n NUMBER := 10;
    PROCEDURE etudeNocopy (n1 IN NUMBER, n2 IN OUT NUMBER, n3 IN OUT   NOCOPY NUMBER) IS
    BEGIN
      n2 := 20;
      DBMS_OUTPUT.PUT_LINE(n1);
      n3 := 30;
      DBMS_OUTPUT.PUT_LINE(n1);
    END etudeNocopy;
     
    BEGIN
      etudeNocopy(n, n, n);
      DBMS_OUTPUT.PUT_LINE(n);
    END;
    le resultat affiche:
    Pouvait vous m'expliquer pourquoi?

    Merci

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 207
    Par défaut
    Salut,

    Je vais essayer :
    En fait si tu veux essayer de comprendre fais le test sans le nocopy et dans ce cas tu devrais avoir comme résultat

    En fait le nocopy signifie que tu passes non pas la valeur, mais la référence (genre un pointeur)

    Donc tu fais etudeNocopy(n,n,b) si reviens à etudeNocopy (n=10,n=10,n=10)

    Etape 1 : n2=20 et affiche , ca renvoi 10=> normal c'est ce qu'on a envoyé
    Etape 2 : n3=30 et affiche n1. Ici on obtient 30 ! n1 est un paramètre d'entrée no modifiable, et prends la donc la valeur de référence (que l'on vient de modifier via n3) c'est pour cela que n1=n3, amuse toi mettre n1 en IN OUT et tu verras que n1 conserve sa valeur.

    Je ne sais pas si je suis clair. mais j'espere que ca te fait avancer;

    Laurent.

    My ORACLE BLOG ==> http://lao-dba.over-blog.com

  3. #3
    Membre confirmé
    Inscrit en
    Mars 2003
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 109
    Par défaut
    Citation Envoyé par lallio Voir le message
    Salut,
    Donc tu fais etudeNocopy(n,n,b) si reviens à etudeNocopy (n=10,n=10,n=10)

    Etape 1 : n2=20 et affiche , ca renvoi 10=> normal c'est ce qu'on a envoyé OK

    Pourquoi ds l'etape 2 on n'affiche pas n1 comme ds l'etape precedente?
    Ds l'etape precedente n1 est aussi IN !!

    Etape 2 : n3=30 et affiche n1. Ici on obtient 30 ! n1 est un paramètre d'entrée no modifiable, et prends la donc la valeur de référence (que l'on vient de modifier via n3) c'est pour cela que n1=n3, amuse toi mettre n1 en IN OUT et tu verras que n1 conserve sa valeur.

    Merci

  4. #4
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par SheikYerbouti dans son Guide PL/SQL
    NOCOPY indique que le paramètre est transmis par référence (pointeur) et non par copie de la valeur
    Par défaut, les paramètres sont transmis par copie, c'est à dire qu'un espace mémoire est créé pour recevoir une copie de la valeur
    avec la clause NOCOPY, aucun espace mémoire supplémentaire n'est créé, c'est donc l'adresse de l'espace mémoire initial qui est transmise, permettant d'une part de ne pas gaspiller la mémoire disponible (surtout lorsqu'il s'agit de grands objets (LOB) et également d'éviter le temps nécessaire à la gestion de ces nouveaux espace mémoire (empilement, dépilement, etc.)
    Quand tu utilises NOCOPY tu modifies directement la valeur de la variable passée en paramètre (dans ton exemple n).
    Quand tu n'utilises pas NOCOPY tu modifies une copie de la variable passée en paramètre. C'est uniquement une fois l'exécution de ta procédure terminée que la valeur de la variable passée en paramètre est modifiée. L'avantage c'est que cela permet d'annuler les modifications faites dans ta procédure (alors qu'avec le NOCOPY cela n'est pas possible).

  5. #5
    Expert confirmé 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
    Par défaut
    Citation Envoyé par plaineR Voir le message
    Quand tu utilises NOCOPY tu modifies directement la valeur de la variable passée en paramètre (dans ton exemple n).
    Quand tu n'utilises pas NOCOPY tu modifies une copie de la variable passée en paramètre.
    Seulement si le paramètre n'est pas de type IN
    Suppose a subprogram declares an IN parameter, an OUT parameter, and an IN OUT parameter. When you call the subprogram, the IN parameter is passed by reference. That is, a pointer to the IN actual parameter is passed to the corresponding formal parameter. So, both parameters reference the same memory location, which holds the value of the actual parameter.

    By default, the OUT and IN OUT parameters are passed by value. That is, the value of the IN OUT actual parameter is copied into the corresponding formal parameter. Then, if the subprogram exits normally, the values assigned to the OUT and IN OUT formal parameters are copied into the corresponding actual parameters.
    Citation Envoyé par plaineR Voir le message
    C'est uniquement une fois l'exécution de ta procédure terminée que la valeur de la variable passée en paramètre est modifiée. L'avantage c'est que cela permet d'annuler les modifications faites dans ta procédure (alors qu'avec le NOCOPY cela n'est pas possible).
    Seulement en cas d'anomalie

    By default, if a subprogram exits with an unhandled exception, the values assigned to its OUT and IN OUT formal parameters are not copied into the corresponding actual parameters, and changes appear to roll back. However, when you specify NOCOPY, assignments to the formal parameters immediately affect the actual parameters as well. So, if the subprogram exits with an unhandled exception, the (possibly unfinished) changes are not "rolled back."

  6. #6
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Seulement si le paramètre n'est pas de type IN
    C'était un peu sous entendu, puisque avec un paramètre de type IN, tu ne peux pas modifier la valeur de la variable passée paramètre

    Citation Envoyé par mnitu Voir le message
    Seulement en cas d'anomalie
    Pas du tout d'accord :
    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
    DECLARE
    n NUMBER := 10;
     
    procedure p1(p in out number) is
    begin
      p := 20;
      dbms_output.put_line ('p=' || p || ' n=' || n);
      p := n;
      dbms_output.put_line ('p=' || p || ' n=' || n);
    end;
     
    procedure p2(p in out nocopy number) is
    begin
      p := 30;
      dbms_output.put_line ('p=' || p || ' n=' || n);
      p := n;
      dbms_output.put_line ('p=' || p || ' n=' || n);
    end;
     
    BEGIN
      p1(n);
      dbms_output.put_line ('Sans nocopy : ' || n);
      p2(n);
      dbms_output.put_line ('Avec nocopy : ' || n);
    END;
    /
     
     
    p=20 n=10
    p=10 n=10
    Sans nocopy : 10
    p=30 n=30
    p=30 n=30
    Avec nocopy : 30

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

Discussions similaires

  1. comprendre le résultat d'une modélisation
    Par ouinih dans le forum R
    Réponses: 0
    Dernier message: 08/09/2011, 23h37
  2. Comprendre un résultat de requête
    Par arcane dans le forum Langage SQL
    Réponses: 3
    Dernier message: 18/10/2008, 17h43
  3. Comprendre le résultat du désassemblage
    Par Lucas Panny dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 13/08/2008, 13h28
  4. Réponses: 4
    Dernier message: 28/09/2002, 00h00
  5. [BDD] Enregistrer le résultat d'une requête
    Par Mowgly dans le forum C++Builder
    Réponses: 5
    Dernier message: 19/06/2002, 15h26

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