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 :

[PL/SQL] : type record et FORALL


Sujet :

Oracle

  1. #1
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut [PL/SQL] : type record et FORALL
    Bonjour à tous,

    Oracle9i Release 9.2.0.1.0 - Production
    PL/SQL Release 9.2.0.1.0 - Production
    OS : windows 2000 server

    je cherche à insérer des données dans une table à partir d'une TABLE DE RECORDS en utilisant le SQL DYNAMIQUE et FORALL

    Insulte rencontrée :

    ERREUR à la ligne 75 :
    ORA-06550: Ligne 75, colonne 51 :
    PLS-00436: restriction de mise en oeuvre : impossible de référencer des champs
    d'une table d'enregistrements BULK In-BIND
    ORA-06550: Ligne 75, colonne 6 :
    PL/SQL: Statement ignored
    un peu de code
    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
     
    DECLARE
    --//--RECORD
    TYPE T_LQ_REC IS RECORD (
         LQ_VLAB_SEQ VARIANCE_LABORATOIRE.VLAB_SEQ%TYPE,
         LQ_ESS_ID ESSAI.ESS_ID%TYPE,
         LQ_PARA_ID PARAMETRES.PARA_ID%TYPE,
         LQ_MATR_ID MATRICE.MATR_ID%TYPE,
         LQ_LOT_ID LOT.LOT_ID%TYPE,
         LQ_METH_ID METHODES.METH_ID%TYPE,
         LQ_POINT_ID RESULTATS.POINT_ID%TYPE,
         LQ_VLAB_MOYENNE VARIANCE_LABORATOIRE.VLAB_MOYENNE%TYPE,
         LQ_VLAB_SRESIDUELLE VARIANCE_LABORATOIRE.VLAB_SRESIDUELLE%TYPE,
         LQ_VLAB_SINTERFLACONS VARIANCE_LABORATOIRE.VLAB_SINTERFLACONS%TYPE,
         LQ_VLAB_SELECTION VARIANCE_LABORATOIRE.VLAB_SELECTION%TYPE,
         LQ_VLAB_LQ VARIANCE_LABORATOIRE.VLAB_LQ%TYPE,      
         LQ_VLAB_MINF VARIANCE_LABORATOIRE.VLAB_LQ_MINF%TYPE,
         LQ_VLAB_MSUP VARIANCE_LABORATOIRE.VLAB_LQ_MSUP%TYPE);
     
    T_LE_LQ T_LQ_REC;
     
    TYPE T_LQ_TAB IS TABLE OF T_LQ_REC;
    T_LES_LQ T_LQ_TAB:=T_LQ_TAB();
     
    BEGIN
     
    --J'alimente mon tableau de records à ce niveau, pas de pb, mon tableau est bien rempli
     
    T_LES_LQ(cpt):=T_LE_LQ;
     
    --Après plusieurs traitements, j'ai à ce niveau un tableau complet de records que je voudrai insérer le plus efficacement possible dans une table.
     
    --Pour cela, voici ce que je fais
    chInsert:='INSERT INTO VARIANCE_LABORATOIRE(VLAB_SEQ, ';
    chInsert:=chInsert||'ESS_ID, ';
    chInsert:=chInsert||'PARA_ID, ';
    chInsert:=chInsert||'MATR_ID, ';
    chInsert:=chInsert||'LOT_ID, ';
    chInsert:=chInsert||'METH_ID, ';
    chInsert:=chInsert||'POINT_ID, ';
    chInsert:=chInsert||'VLAB_MOYENNE, ';
    chInsert:=chInsert||'VLAB_SRESIDUELLE, ';
    chInsert:=chInsert||'VLAB_SINTERFLACONS, ';
    chInsert:=chInsert||'VLAB_SELECTION, ';
    chInsert:=chInsert||'VLAB_LQ,VLAB_LQ_MINF,VLAB_LQ_MSUP) ';
    chInsert:=chInsert||'VALUES (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14)';
     
    FORALL i IN T_LES_LQ.FIRST..T_LES_LQ.LAST
         EXECUTE IMMEDIATE chInsert USING T_LES_LQ(i).LQ_VLAB_SEQ,
                T_LES_LQ(i).LQ_ESS_ID,
                T_LES_LQ(i).LQ_PARA_ID,
                T_LES_LQ(i).LQ_MATR_ID,
                T_LES_LQ(i).LQ_LOT_ID,
                T_LES_LQ(i).LQ_METH_ID,
                T_LES_LQ(i).LQ_POINT_ID,
                T_LES_LQ(i).LQ_VLAB_MOYENNE,
                T_LES_LQ(i).LQ_VLAB_SRESIDUELLE,
                T_LES_LQ(i).LQ_VLAB_SINTERFLACONS,
                T_LES_LQ(i).LQ_VLAB_SELECTION,
                T_LES_LQ(i).LQ_VLAB_LQ,
                T_LES_LQ(i).LQ_VLAB_MINF,
                T_LES_LQ(i).LQ_VLAB_MSUP;
     
    END;
    Et me fais jeter !! si je fais l'insertion sans passer par une variable compteur (ici i) çà marche !!

    exemple :


    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
     
    EXECUTE IMMEDIATE chInsert USING T_LES_LQ(1).LQ_VLAB_SEQ,
                T_LES_LQ(1).LQ_ESS_ID,
                T_LES_LQ(1).LQ_PARA_ID,
                T_LES_LQ(1).LQ_MATR_ID,
                T_LES_LQ(1).LQ_LOT_ID,
                T_LES_LQ(1).LQ_METH_ID,
                T_LES_LQ(1).LQ_POINT_ID,
                T_LES_LQ(1).LQ_VLAB_MOYENNE,
                T_LES_LQ(1).LQ_VLAB_SRESIDUELLE,
                T_LES_LQ(1).LQ_VLAB_SINTERFLACONS,
                T_LES_LQ(1).LQ_VLAB_SELECTION,
                T_LES_LQ(1).LQ_VLAB_LQ,
                T_LES_LQ(1).LQ_VLAB_MINF,
                T_LES_LQ(1).LQ_VLAB_MSUP;
    kelke chose m'échappe !! FORALL ne serait-il point adapté pour des types RECORDS !!!

    Merci de votre aide

    @

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075

  3. #3
    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
    Points : 3 609
    Points
    3 609
    Par défaut Re: [PL/SQL] : type record et FORALL
    Citation Envoyé par PpPool
    kelke chose m'échappe !! FORALL ne serait-il point adapté pour des types RECORDS !!!
    Vu ton message d'erreur, j'aurais dit que forall n'étais pas adapté pour les bind variable de ton execute immediate.

    Ne peux-tu pas éviter le sql dynamique ?

  4. #4
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut
    Citation Envoyé par Fred_D
    Bonjour Orafrance !! (oups Fred_D)

    je l'ai lu en effet. FORALL avec des binds variables+collections semble ne pas fonctionner dans mon cas.


  5. #5
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut Re: [PL/SQL] : type record et FORALL
    Citation Envoyé par plaineR
    Citation Envoyé par PpPool
    kelke chose m'échappe !! FORALL ne serait-il point adapté pour des types RECORDS !!!
    Vu ton message d'erreur, j'aurais dit que forall n'étais pas adapté pour les bind variable de ton execute immediate.

    Ne peux-tu pas éviter le sql dynamique ?
    Bonjour plaineR, et merci de ta réponse

    malheureusement je ne peux pas éviter le SQL dynamique !!!
    et en effet, je suis arrivé à la même conclusion que toi !!!

    Pourtant dans les tutos de sheiK sur DVP, il y a bien un exemple d'utilisation de FORALL avec des collections, mais pas de type RECORDS !!


  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par PpPool
    Bonjour Orafrance !! (oups Fred_D)
    argh... je suis démasqué

    En effet, la collection de record ne fonctionne pas (d'après mes propres essais également), tu dois déclarer autant de variable que nécessaire. Eventuellement, tu peux peut-être t'en sortir en créant un objet, un type SQL en fait mais là j'ai jamais eu le temps de creuser

  7. #7
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Pourquoi EXECUTE IMMEDIATE ?
    Pourquoi ne pas utiliser directement l'ordre INSERT dans votre commande FORALL ?

    A partir d'oracle9i, les copies d'informations par blocs peuvent être effectuées directement dans les collections d'enregistrements
    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
    SQL> Declare
      2    TYPE   TYP_TAB_TEST IS TABLE OF TEST%ROWTYPE ;
      3    tabrec TYP_TAB_TEST ;
      4    CURSOR C_test is select A, B From TEST ;
      5  begin
      6     -- chargement de la collection depuis la table --
      7     Select A, B BULK COLLECT into tabrec From TEST ;
      8     
      9     -- insertion de lignes à partir de la collection --
     10     Forall i in tabrec.first..tabrec.last
     11         insert into TEST values tabrec(i) ;
     12      
     13     -- mise à jour des données de la collection --
     14     For i in tabrec.first..tabrec.last Loop
     15         tabrec(i).B := tabrec(i).B * 2 ;    
     16     End loop ;
     17     
     18     -- utilisation du curseur --
     19     Open C_test ;
     20     Fetch C_test BULK COLLECT Into tabrec ;
     21     Close C_test ;
     22         
     23  End ;
     24  /
     
    Procédure PL/SQL terminée avec succès.

  8. #8
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut
    Citation Envoyé par SheikYerbouti
    Pourquoi EXECUTE IMMEDIATE ?
    Pourquoi ne pas utiliser directement l'ordre INSERT dans votre commande FORALL ?
    Bonjour sheik et merci de ton aide
    mon ordre d'insertion est lui-même dynamique. je ne l'ai pas précisé dans le post pour faire simple.
    D'où la nécessité du EXECUTE IMMEDIATE.

    Ce que j'ai fait et qui fonctionne (mais pas optimisé) :

    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
     
    FOR i IN T_LES_LQ.FIRST..T_LES_LQ.LAST
    LOOP
         EXECUTE IMMEDIATE chInsert USING T_LES_LQ(i).LQ_VLAB_SEQ,
                T_LES_LQ(i).LQ_ESS_ID,
                T_LES_LQ(i).LQ_PARA_ID,
                T_LES_LQ(i).LQ_MATR_ID,
                T_LES_LQ(i).LQ_LOT_ID,
                T_LES_LQ(i).LQ_METH_ID,
                T_LES_LQ(i).LQ_POINT_ID,
                T_LES_LQ(i).LQ_VLAB_MOYENNE,
                T_LES_LQ(i).LQ_VLAB_SRESIDUELLE,
                T_LES_LQ(i).LQ_VLAB_SINTERFLACONS,
                T_LES_LQ(i).LQ_VLAB_SELECTION,
                T_LES_LQ(i).LQ_VLAB_LQ,
                T_LES_LQ(i).LQ_VLAB_MINF,
                T_LES_LQ(i).LQ_VLAB_MSUP;
    END LOOP;
    je rejoinds Fred_D (je préférais Orafrance, y'à rien à faire ), dans mon cas FORALL ne fonctionne pas avec les collections de type RECORD;

    J'ai bien parcouru ton tuto super bien fait sur DVP, et en effet cela marche sans problème dans d'autres cas !!


    je laisse ouvert au cas où le post pour ce soir.

    @

  9. #9
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Le problème n'est pas l'utilisation du FORALL avec les collections d'enregistrements, mais plutôt le Binding dans l'instruction EXECUTE IMMEDIATE.

  10. #10
    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
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par PpPool
    je rejoinds Fred_D (je préférais Orafrance, y'à rien à faire ), dans mon cas FORALL ne fonctionne pas avec les collections de type RECORD;

    Citation Envoyé par SheikYerbouti
    A partir d'oracle9i, les copies d'informations par blocs peuvent être effectuées directement dans les collections d'enregistrements
    Ce qui me confirme dans mon idée que le problème vient bien du sql dynamique et non des collections de record.

    Moi aussi je préférais orafrance , question d'habitude sans doute !

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    un responsable SGBD se doit de rester impartial

Discussions similaires

  1. [PLSQL] TYPE RECORD
    Par romuald9999 dans le forum Oracle
    Réponses: 13
    Dernier message: 19/08/2004, 15h18
  2. PL/SQL ORACLE (Record Dans un Varchar2)
    Par argoet dans le forum PL/SQL
    Réponses: 24
    Dernier message: 14/05/2004, 16h06
  3. [LG]fichier typé; record et pointeurs
    Par rigel dans le forum Langage
    Réponses: 6
    Dernier message: 12/05/2004, 16h12
  4. [LG]Resultat de fonction de type Record ?
    Par Mike888 dans le forum Langage
    Réponses: 10
    Dernier message: 24/01/2004, 22h48
  5. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10

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