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 :

boucle dans INSERT


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Par défaut boucle dans INSERT
    bonjour,

    je travaille avec SQL developper.
    Je fais de l'appariement de libellé de voie.
    Je cherche à insérer dans une table RECAP, les données d'une autre table (table A), tout en leur affectaant un niveau d'appariement..

    Niv 0: libelle identique entre les deux tables
    Niv1 : type de voie et mot classant identiques...
    Niv 2: type de voies différents et mot classants identiques.
    Niv 3 : absence de voies

    Le problème se pose au niv 2. les données s'apparient bien mais il me reste des libellés qu'il ne m'a pas trouvé.

    Par exemple,
    Dans la TABLE A, j'ai AVENUE TOURNESOLS, BOULEVARD TOURNESOLS et TRAVERSE DES TOURNESOLS.
    Dans ma table RECAP, j'ai AVENUE DES TOURNESOLS et BOULEVARD DES TOURNESOLS.

    Il m'identifie bien AVENUE TOURNESOLS et AVENUE DES TOURNESOLS en niv 1.
    Meme chose pour les Boulevard.

    Cependant, il ne m'a pas identifier TRAVERSE DES TOURNESOLS en niveau 2. Il me le considère comme une absence de voie (niv 3). Cette voie n'est pas absente mais mal appariée.

    Je cherche alors à créer une boucle dans un INSERT.

    Objectif : Insérer les voies présentes dans la table A et pas dans la table RECAP,dans la table RECAP qui répondent au critères du niveau 2.
    que la boucle tourne jusqu'à qu'elle n'est plus trouvée de voie correspondant au niv2.

    Débutante depuis peu avec Oracle et le SQL. Je ne sais pas du tout comment m'y prendre.

    Je pensais utiliser une boucle WHILE, vu que je veux que la boucle réponde aux conditions type de voie différents et mot_classants identiques.

    Quelqu'un a t-il déjà eu ce type de problème et me donner quelques conseils ???

    Merci d'avance

  2. #2
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    Pour t'aider, il faudrait en savoir un peu plus.
    Que veux-dire "MOT CLASSANT" ?
    IL faudrait également la description de tes tables avec les clés primaire et les relations entre tables !
    A première vue, pas besoin de boucle.
    Du simple SQL devrait suffire.

  3. #3
    Membre averti
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Par défaut
    Mot classant est le dernier mot du libellé.
    J'ai 3 tables.
    Table H : avec des libellés d'une commune A
    Table S : avec les libellés de la même commune.
    RECAP table de réception des tables H et S

    Je cherche à apparier ces 2 tables en affectant des niveaux d'appariement.

    J'ai déjà inséré les données de ma 1ère table adresse(table H).
    Je souhaite apparier les données de ma table S avec les données de la table H dans la table RECAP.

    TABLE_H
    ---------

    PID_H varchar2
    type_voie_h varchar2
    libelle_h (nom complet) varchar2
    mot_classant_h varchar2


    TABLE_S
    ---------

    PID_s varchar2
    type_voie varchar2
    com_nme varchar2
    libelle (nom complet) varchar2
    mot_classant varchar2


    RECAP
    -------
    PID_H varchar2
    PID_S varchar2
    type_voie_h varchar2
    type_voievarchar2
    libelle_h (nom complet) varchar2
    com_nme varchar2
    mot_classant_h varchar2
    mot_classant varchar2
    niv_app_h_s (niv 0,1,2,3) integer

    1/ insertion de la table H dans RECAP.
    2/ appariement de la table H et S dans RECAP, avec des update de S dans RECAP.

    EN gros je veux faire une boucle pour être sûr que tous les libellés de ma table S vont être dans ma table RECAP.

    Ce qui n'était pas le cas quand je fais un update pour chaque niveau.

    Par exemple,pour le niveau 1 voici le 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
    update RECAP set 
    (PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_CLASSANT_S,niv_app_h_s,campagne) 
     =(select PID,type_voie,COM_NME,mot_classant,1,campagne from table_S
        where TYPE_VOIE=TYPE_VOIE_H
        and MOT_Classant=MOT_Classant_H
        and table_S.INSEE=RECAP.INSEE and rownum =1) 
     
    where  
        niv_app_h_s is null and exists 
    (select * from Table_s
        where TYPE_VOIE=TYPE_VOIE_H
        and MOT_Classant=mot_Classant_H 
        and table_s.INSEE=RECAP.INSEE 
        and ROWNUM=1
        );
    ce code marche parfaitement mais quand je l'applique pour mon niveau 2 avec ma condition type_voie <> type_voie_h et mot_classant=mot_classant_h.
    Il y a des voies de S qui ne m'insère pas dans RECAP.
    Par exemple dans RECAP,
    TYPE_VOIE_H | LIBELLE_H | MOT_CLASSANT_H |
    ------------------------------------------------------------------------
    AVENUE | AVENUE COMMANDANT BERNARD | BERNARD

    TYPE_VOIE_S | LIBELLE_S | MOT_CLASSANT_S | Niveau appariement
    ------------------------------------------------------------------------
    IMPASSE IMPASSE BERNARD BERNARD 2



    Mais si j'ai en plus dans Table S : TRAVERSE BERNARD.
    Moi ce que j'attends c'est :

    TYPE_VOIE_H | LIBELLE_H | MOT_CLASSANT_H |
    ------------------------------------------------------------------------
    AVENUE | AVENUE COMMANDANT BERNARD | BERNARD

    TYPE_VOIE_S | LIBELLE_S | MOT_CLASSANT_S | Niveau appariement
    ------------------------------------------------------------------------
    TRAVERSE TRAVERSE BERNARD BERNARD 2

    ce n'est pas ce qui se passe.
    Il considère TRAVERSE BERNARD comme Absente de la table H alors que le niveau 2 existe.

    Suite à ce constat, je souhaite faire une boucle pour tout récupérer.

    Voilà ce que j'ai tenté :
    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
    DECLARE
     
    CURSOR C_Niv2 is
    select pid
    from table_s
    where pid not in (select pid_s
                            from recap);
     
     
    begin
     
    for c in C_Niv2
     
    Loop
     
    exit when c_Niv2%NOTFOUND;
    update RECAP
    set(PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_classant_S,niv_app_h_s,campagne) 
     =(select PID,type_voie,COM_NME,mot_classant,2,campagne 
        from table_s
     
    where type_voie<> type_voie_s
    and mot_directeur_s=mot_directeur_s);
    end loop;
    close C_Niv2;
    end;
    et j'ai cette erreur :
    Error report:
    ORA-01001: curseur non valide
    ORA-06512: à ligne 25
    01001. 00000 - "invalid cursor" !!

    Pouvez m'orienter afin que je puisse comprendre comment faire une boucle dans mon cas? Merci

  4. #4
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    Deja :
    Ne pas faire

    • Open cursor
    • Exit when not found
    • Close cursor


    car ces trois opérations sont IMPLICITES par l'utilisation de la boucle
    FOR curseur IN....
    L'erreur vient du fait que vous faites un CLOSE déjà fermé (par la sortie de la boucle)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DECLARE  
     CURSOR C_Niv2 IS SELECT pid FROM table_s 
    WHERE pid NOT IN (SELECT pid_s FROM recap);
    begin   
    FOR c IN C_Niv2 Loop   
    UPDATE RECAP SET(PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_classant_S,niv_app_h_s,campagne)   =(SELECT PID,type_voie,COM_NME,mot_classant,2,campagne
          FROM table_s
          WHERE type_voie<> type_voie_s 
          AND mot_directeur_s=mot_directeur_s); 
    end loop;
    end;

  5. #5
    Membre averti
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Par défaut
    je viens de lancer le script !
    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   
    CURSOR C_Niv2 IS SELECT pid FROM sdis_2010_t1 WHERE pid not in (SELECT pid_s                       
                                                                                FROM recap_test);                           
    begin   
    FOR c IN 1..2
    Loop   
    UPDATE RECAP_test SET(PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_directeur_S,niv_app_h_s,campagne)   
    =(SELECT PID,type_voie,COM_NME,mot_directeur,2,campagne     
            FROM sdis_2010_t1    
            WHERE type_voie<> type_voie_s 
            AND mot_directeur_s=mot_directeur_s); 
    end loop;  
    end;
    et cela me donne une erreur

    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
    Error starting at line 1 in command:
    DECLARE   
    CURSOR C_Niv2 IS SELECT pid FROM sdis_2010_t1 WHERE pid not in (SELECT pid_s                       
                                                                                FROM recap_test);                           
    begin   
    FOR c IN 1..2
    Loop   
    DBMS_OUTPUT.PUT_LINE( c );
    UPDATE RECAP_test SET(PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_directeur_S,niv_app_h_s,campagne)   
    =(SELECT PID,type_voie,COM_NME,mot_directeur,2,campagne     
            FROM sdis_2010_t1    
            WHERE type_voie<> type_voie_s 
            AND mot_directeur_s=mot_directeur_s); 
    end loop;  
    end;
    Error report:
    ORA-01427: sous-interrogation ramenant un enregistrement de plus d'une ligne
    ORA-06512: à ligne 8
    01427. 00000 -  "single-row subquery returns more than one row"
    *Cause:    
    *Action:
    je me suis surement loupée quelque part !!
    j'ai du louper quelquechose mais je ne vois pas trop !!

  6. #6
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    Il faut mettre des alias ou préfixer les colonnes pour discerner le colonnes de même nom dans chacune des tables
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE RECAP_test SET(PID_S,TYPE_VOIE_S,LIBELLE_VOIE_S,MOT_directeur_S,niv_app_h_s,campagne)    =(SELECT PID,type_voie,COM_NME,mot_directeur,2,campagne              FROM sdis_2010_t1             WHERE type_voie<> type_voie_s          AND RECAP.mot_directeur_s=sdis_2010_T1.mot_directeur_s)
    Sinon mot_directeur_s=mot_directeur_s est TOUJOURS VRAI et raméne donc plus d'une ligne !!!!!

Discussions similaires

  1. [MySQL] Boucle d'insertion dans un table mysql
    Par roy2work dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 23/10/2013, 16h37
  2. Boucle dans une requete insertion
    Par Avatar69 dans le forum Développement
    Réponses: 4
    Dernier message: 02/03/2012, 00h35
  3. ajouter des dates délémitées dans INSERT INTO ?
    Par samlepiratepaddy dans le forum Access
    Réponses: 8
    Dernier message: 27/09/2005, 08h12
  4. Creer une boucle dans une requête ???
    Par fdloisel dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 26/10/2004, 14h05
  5. Notion de boucles dans Business Object
    Par lionelEIGIP dans le forum Deski
    Réponses: 1
    Dernier message: 08/04/2004, 11h26

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