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

SQL Oracle Discussion :

Insert select sur un champ Long


Sujet :

SQL Oracle

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut Insert select sur un champ Long
    Bonjours à tous.

    J'ai le problème suivant :

    Dans mon application je dois charger depuis un fichier plat des données dans une table.
    Cependant, avant d'insérer dans la table cible , j'importe les données dans une table temporaire (sans clé, ni autre contraintes) qui a la même structure que ma table cible mais avec un champ Error_flag pour pointer les données du fichier plats posant des probléme de contraites d'intégrité.

    Aprés l'éxécution d'un traitement sur la qualité des données lignes à ligne de ma table temporaire, J'effectue un insert select de la table temporaire dans ma table cible que pour les lignes dont le Error_flag est vide.

    C'est la qu'arrive le probléme : Toutes les données sont bien insérer sauf le champ de type Long.
    J'ai essayé avec un update avec jointure sur les deux tables, Oracle n'accepte pas ce type d'update avec un long :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE Table_cible a
       SET a.comments = (SELECT b.comments
                           FROM Table_temp b
                          WHERE b.clé = a.clé
    Une idée ?

    Merci d'avance.

  2. #2
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    intéressant. Ca fait un moment que je n'ai plus fait de long, j'imagine qu'il doit y avoir une soluce toute simple.

    Bon, en plsql je pourrais imaginer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    begin 
      for f in (SELECT a.cle, b.comments FROM lsc_Table_cible a, lsc_Table_temp b WHERE b.cle = a.cle)
      loop
        UPDATE lsc_Table_cible SET comments = f.comments WHERE cle = f.cle;
      end loop;
    end;
    /

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut
    N'étant pas à l'aise en PL/SQL, j'ai beaucoup de difficulté à développer cette soluce. voici ce que j'ai tenté tout de mê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
    CREATE OR REPLACE function VB_TEST(
      vb_s_param1 in varchar2)
      return varchar2
     
    is
     
      vb_s_result VARCHAR2(32767);
     
     
    BEGIN
       FOR f IN  (SELECT a.siren_num, a.vb_seq_num, b.comments
                    FROM ps_vb_crdt_comment a, ps_vb_crtdescr_tao b
                   WHERE a.siren_num = b.siren_num
                     AND a.vb_seq_num = b.vb_seq_num
                     AND b.error_flag = 'Y')
       LOOP
          UPDATE ps_vb_crdt_comment
             SET comments = f.comments
           WHERE siren_num = f.siren_num AND vb_seq_num = f.vb_seq_num;
       END LOOP;
     
     
    vb_s_result := 'Fin';
     
    return vb_s_result;
    end VB_TEST;
    /
    L'erreur se situe au niveau de la synthaxe du for car l'expression du In n'est pas considérer comme un entier.
    Dans mon exemple, siren_num (Char) et seq_num(Integer) sont clé primaire de la table... Je pense que le probléme vient de la...

  4. #4
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    quelle est ta version?

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut
    Si on parle de la base Oracle, il s'agit de 10.2.0.4.0

  6. #6
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    et l'erreur, c'est quoi?

    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
     
    SQL> create table ps_vb_crdt_comment(
      2    siren_num char(10),vb_seq_num number,comments long);
     
    Table created.
     
    SQL> create table ps_vb_crtdescr_tao(
      2    siren_num char(10),vb_seq_num number,error_flag varchar2(1),comments long);
     
    Table created.
     
    SQL> CREATE OR REPLACE FUNCTION VB_TEST(
      2    vb_s_param1 IN varchar2)
      3    RETURN varchar2
      4  
      5  IS
      6  
      7    vb_s_result VARCHAR2(32767);
      8  
      9  
     10  BEGIN
     11     FOR f IN  (SELECT a.siren_num, a.vb_seq_num, b.comments
     12                  FROM ps_vb_crdt_comment a, ps_vb_crtdescr_tao b
     13                 WHERE a.siren_num = b.siren_num
     14                   AND a.vb_seq_num = b.vb_seq_num
     15                   AND b.error_flag = 'Y')
     16     LOOP
     17        UPDATE ps_vb_crdt_comment
     18           SET comments = f.comments
     19         WHERE siren_num = f.siren_num AND vb_seq_num = f.vb_seq_num;
     20     END LOOP;
     21  
     22  
     23  vb_s_result := 'Fin';
     24  
     25  RETURN vb_s_result;
     26  end VB_TEST;
     27  /
     
    Function created.
     
    SQL> sho error;
    No errors.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut
    Re bonjour et merci pour ta réponse.

    J'ai revérifier mon code, et j'avais également oublié un troisiéme champs de la clé (VB_TYPE_ITEM). Après la correction cela ne change rien. La fonction se compile correctement mais l'éxécution ne rempli pas ma table.

    Voici le code de la fonction :

    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
    CREATE OR REPLACE FUNCTION VB_TEST(
          vb_s_param1 IN varchar2)
         RETURN varchar2
     
        IS
     
         vb_s_result VARCHAR2(32767);
     
        BEGIN
         FOR f IN  (SELECT a.siren_num, a.vb_seq_num, a.VB_TYPE_ITEM, b.comments
                       FROM ps_vb_crdt_comment a, ps_vb_crtdescr_tao b
                     WHERE a.siren_num = b.siren_num
                       AND a.vb_seq_num = b.vb_seq_num
    				   and a.VB_TYPE_ITEM = b.VB_TYPE_ITEM
                       AND b.error_flag = 'Y')
         LOOP
            UPDATE ps_vb_crdt_comment
               SET comments = f.comments
             WHERE siren_num = f.siren_num AND vb_seq_num = f.vb_seq_num AND VB_TYPE_ITEM= f.VB_TYPE_ITEM;
         END LOOP;
     
     
      vb_s_result := 'Fin';
     
      RETURN vb_s_result;
       end VB_TEST;
      /
    Petite précision sur mon environement technique : Je travail sur ma base Oracle avec le client Toad.
    Toad propose un débuggeur de fonction plsql que j'utilise pour corriger les erreurs. Cependant, à la fin de la compilation, je n'ai aucune Erreur de compilation mais une message box windows s'affiche avec le message suivant :

    'IN' is not a valid integer value.

    Pourtant quand j'éxécute ce sript pour créer la fonction, je n'ai aucune erreur.

    Pour appeler la fonction j'utilise le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select VB_TEST('1') from dual
    Il y a bien quelque chose qui tourne mais ça ne remplie pas ma table cible...

  8. #8
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    il n'est pas possible d'appeler une fonction qui fait un UPDATE depuis un select.

    Pour avoir une erreur que l'on puisse comprendre, utilise sqlplus et pas toad.

    dans sqlplus, que te donne ceci?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    declare 
      x varchar2(400);
    begin 
      x:=VB_TEST('1');
    end;
    /

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut
    Dans Sql plus, voici ce que me donne la commande :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SQL> declare 
      2    x varchar2(400);
      3  begin 
      4    x:=VB_TEST('1');
      5  end;
      6  /
     
    Procédure PL/SQL terminée avec succès.
     
    SQL> commit
      2  ;
     
    Validation effectuée.
    Mais ma table cible n'est pas chargée. Le champ commentaire reste vide.

  10. #10
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    chez moi ça marche au poil...
    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
     
    SQL> CREATE TABLE ps_vb_crdt_comment(
    siren_num char(10),vb_seq_num number,
    comments long)
    Table created.
    SQL> CREATE TABLE ps_vb_crtdescr_tao(
    siren_num char(10),vb_seq_num number,error_flag varchar2(1),
    comments long)
    Table created.
    SQL> CREATE OR REPLACE FUNCTION VB_TEST(
    vb_s_param1 IN varchar2)
    RETURN varchar2
    IS
    vb_s_result VARCHAR2(32767);
    BEGIN
    FOR f IN  (SELECT a.siren_num, a.vb_seq_num, b.comments
    FROM ps_vb_crdt_comment a, ps_vb_crtdescr_tao b
    WHERE a.siren_num = b.siren_num
    AND a.vb_seq_num = b.vb_seq_num
    AND b.error_flag = 'Y')
    LOOP
    UPDATE ps_vb_crdt_comment
    SET comments = f.comments
    WHERE siren_num = f.siren_num AND vb_seq_num = f.vb_seq_num;
    END LOOP;
    vb_s_result := 'Fin';
    RETURN vb_s_result;
    end VB_TEST;
    Function created.
    SQL> sho error
    No errors.
    SQL> insert into ps_vb_crdt_comment(
      siren_num,vb_seq_num,comments)
    values(
      'A',1,null)
    1 row created.
    SQL> insert into ps_vb_crtdescr_tao(
      siren_num ,vb_seq_num ,error_flag ,comments )
    values(
      'A',1,'Y','blabla')
    1 row created.
    SQL> select comments from ps_vb_crdt_comment
     
    COMMENTS
    ----------------------------------------------------------------------
     
     
    1 row selected.
    SQL> declare 
      x varchar2(400);
    begin 
      x:=VB_TEST('1');
    end;
    PL/SQL procedure successfully completed.
    SQL> select comments from ps_vb_crdt_comment
     
    COMMENTS
    ----------------------------------------------------------------------
    blabla
     
    1 row selected.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 94
    Par défaut
    En effet, ça marche.

    Je viens de trouver mon erreur : La valeur de error_flag. Les lignes valides avec un commentaire sont à 'N' et non 'Y'...

    Forcément avec les bonnes conditions... ça marche tout de suite mieux.

    Ta fonction marche nickel :

    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
    SQL> CREATE OR REPLACE FUNCTION VB_TEST(
      2  vb_s_param1 IN varchar2)
      3  RETURN varchar2
      4  IS
      5  vb_s_result VARCHAR2(32767);
      6  BEGIN
      7  FOR f IN  (SELECT a.siren_num, a.vb_seq_num, a.vb_type_item, b.comments
      8  FROM ps_vb_crdt_comment a, ps_vb_crtdescr_tao b
      9  WHERE a.siren_num = b.siren_num
     10  AND a.vb_seq_num = b.vb_seq_num
     11  and a.vb_type_item = b.vb_type_item
     12  AND b.error_flag = 'N')
     13  LOOP
     14  UPDATE ps_vb_crdt_comment
     15  SET comments = f.comments
     16  WHERE siren_num = f.siren_num AND vb_seq_num = f.vb_seq_num and vb_type_item = f.vb_type_item;
     17  END LOOP;
     18  vb_s_result := 'Fin';
     19  RETURN vb_s_result;
     20  end VB_TEST;
     21  /
     
    Fonction créée.
     
    SQL> declare 
      2    x varchar2(400);
      3  begin 
      4    x:=VB_TEST('1');
      5  end;
      6  /
     
    Procédure PL/SQL terminée avec succès.
     
    SQL> commit;
     
    Validation effectuée.
     
    SQL> select count(*) from ps_vb_crdt_comment where comments is not null
      2  ;
     
      COUNT(*)
    ----------
       1951250
    Merci beaucoup pour tes réponses, ce morceau de code me permet enfin de compléter mon traitement de reprise de données.

    l'opération prend quelques minutes (3-4 min) pour 2000000 de lignes mais sur un traitement qui dure déja 4 heurs ça me parait largement convenable.

    Merci beaucoup.

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

Discussions similaires

  1. Recherche sur un champ LONG
    Par Endymion222 dans le forum Oracle
    Réponses: 14
    Dernier message: 29/11/2005, 14h31
  2. SELECT sur un champ avec accent
    Par Bibicmoi dans le forum Requêtes
    Réponses: 6
    Dernier message: 21/08/2005, 12h20
  3. pb avec select sur deux champs
    Par graphicsxp dans le forum Langage SQL
    Réponses: 7
    Dernier message: 22/03/2005, 15h30
  4. insert-select sur 2 base différente
    Par gskoala dans le forum Paradox
    Réponses: 2
    Dernier message: 16/11/2004, 15h11
  5. select sur un champ de type LONG
    Par ppd dans le forum Langage SQL
    Réponses: 2
    Dernier message: 03/09/2004, 18h19

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