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 :

Assignation entre variables %ROWTYPE


Sujet :

PL/SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2007
    Messages : 35
    Points : 28
    Points
    28
    Par défaut Assignation entre variables %ROWTYPE
    bonjour,

    j'essaie de copier le contenu d'une variable de type %ROWTYPE dans une autre mais pas moyen . Le second %ROWTYPE est identique au premier, à l'exception près qu'il y a une colonne de plus:

    TABLE historique
    id, etat_p, mnt_p, (plus de 50 colonnes) ...

    TABLE historique_tmp
    mêmes colonnes que la table historique, mais avec en plus la colonne qui suit:
    distribution number;

    Ça me donne une erreur à la compilation:
    PLS-00382: expression is of wrong type

    C'est tiré d'une procédure stockée sur Oracle 11g:
    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
     
    CURSOR cur_historique IS 
    select * from historique;
     
    l_historique historique%ROWTYPE;
    l_historique_tmp historique_tmp%ROWTYPE;
     
    l_aleatoire number;
     
    OPEN cur_historique;
    LOOP
      FETCH cur_historique INTO l_historique; 
      EXIT WHEN cur_historique%NOTFOUND;
     
      l_aleatoire := FCT_ALEATOIRE();
      l_historique_tmp := l_historique;  -- PLS-00382: expression is of wrong type
      l_historique_tmp.distribution := l_aleatoire;
     
      INSERT INTO historique_tmp t VALUES l_historique_tmp;
    END LOOP;
    CLOSE cur_historique;

  2. #2
    Membre expérimenté Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Points : 1 332
    Points
    1 332
    Par défaut
    c'est peut etre un FORALL que tu veux faire ...

    il y a des exemples ici

    http://sheikyerbouti.developpez.com/pl_sql/?page=Chap5

    asktom.oracle.com tahiti.oracle.com otn.oracle.com

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.


    phrase chinoise issue du Huainanzi

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2007
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    L'ordre SQL doit être INSERT, UPDATE ou DELETE en relation avec au moins une collection 
    Il doit exister des éléments dans la collection pour toutes les valeurs d'indice de l'instruction FORALL
    Les collections ne sont pas utilisés ici. En fait, le coeur du problème réside dans le fait que ça serait pratique de lire un %ROWTYPE en provenance d'une table, puis de l'insérer dans une autre table, cette dernière contenant une colonne de plus (donc un %ROWTYPE différent).

    Je me demandais si il existait un truc pour faire ça ?

  4. #4
    Membre expérimenté Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Points : 1 332
    Points
    1 332
    Par défaut
    comme le message d'erreur l'indique ce n'est pas possible !!!

    pourquoi ne pas faire un FORALL ???

    asktom.oracle.com tahiti.oracle.com otn.oracle.com

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.


    phrase chinoise issue du Huainanzi

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2007
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    je ne suis pas certain de comprendre comment un FORALL s'applique ici ?

  6. #6
    Membre expérimenté Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Points : 1 332
    Points
    1 332
    Par défaut
    tu peux adapter un truc comme ca


    Code sql : 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
     
    CREATE TABLE TEMp_EMP AS
    SELECT *
    FROM EMP
    WHERE 1=2;
     
    DECLARE
     CURSOR cur IS
     SELECT *
     FROM EMP;
     
     TYPE fetch_array IS TABLE OF cur%ROWTYPE;
     s_array fetch_array;
    BEGIN
     OPEN cur;
       LOOP
        FETCH cur BULK COLLECT INTO s_array ;
     
        FORALL i IN 1..s_array.COUNT
        INSERT INTO TEMP_EMP VALUES s_array(i);
     
        EXIT WHEN cur%NOTFOUND;
      END LOOP;
    CLOSE cur;
      COMMIT;
    END;
    /

    asktom.oracle.com tahiti.oracle.com otn.oracle.com

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.


    phrase chinoise issue du Huainanzi

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2007
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Bon à titre informatif voici une version corrigée:
    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
    CURSOR cur_historique_tmp IS 
    SELECT * FROM historique_tmp;
     
    TYPE t_historique_tmp IS TABLE OF cur_historique_tmp%ROWTYPE;
    v_tablo_historique_tmp t_historique_tmp;
    
    OPEN cur_historique_tmp ;
    LOOP
      FETCH cur_historique_tmp BULK COLLECT INTO v_tablo_historique_tmp; 
    
      FORALL i IN 1 .. v_tablo_historique_tmp.COUNT
        -- Insérer les valeurs de la table temporaire vers la table cible
        -- en omettant d'insérer le dernier champ, exclusif à la table tmp
        INSERT INTO historique(id, etat_p, mnt_p, etc.)
        VALUES (v_tablo_historique_tmp(i).id, v_tablo_historique_tmp(i).etat_p, v_tablo_historique_tmp(i).mnt_p, etc.);
    
      EXIT WHEN cur_historique_tmp%NOTFOUND; 
    END LOOP;
    CLOSE cur_historique_tmp ;
    Avantages: Performance améliorée grâce au BULK-Binding
    Inconvénients: Évolutivité restreinte car les colonnes doivent être déclinées

    La solution idéale serait de ne pas nommer les colonnes explicitement, car un ajout de colonne implique de la maintenance.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2007
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    qui peut être abrégé de la sorte (voir post précédent) car tout les champs de la table cible sont renseignés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      FORALL i IN 1 .. v_tablo_historique_tmp.COUNT
        INSERT INTO historique
        VALUES (v_tablo_historique_tmp(i).id, v_tablo_historique_tmp(i).etat_p, v_tablo_historique_tmp(i).mnt_p, etc.);
    de cette façon, le nom des colonnes n'est déclinée que dans le VALUES.

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

Discussions similaires

  1. [VBA] liens entre variables de formulaires
    Par le_niak dans le forum Access
    Réponses: 9
    Dernier message: 28/09/2006, 10h55
  2. Assigner valeurs variables comp. TextArea
    Par delavega dans le forum Flash
    Réponses: 1
    Dernier message: 07/09/2006, 11h27
  3. Réponses: 13
    Dernier message: 30/05/2006, 16h00
  4. Réponses: 2
    Dernier message: 13/03/2006, 11h47
  5. [VB.Net]Comment assigner contenu variable> nom variable ?
    Par jazz matazz dans le forum VB.NET
    Réponses: 4
    Dernier message: 03/02/2006, 17h28

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