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

WinDev Discussion :

Suppression doublons BDD


Sujet :

WinDev

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 80
    Par défaut Suppression doublons BDD
    Bonjour à tous,

    J'ai une application qui utilise une BDD Hyperfile qui doit être alimentée par des imports successifs de fichier csv.

    Pour les imports, tout est ok, j'en profite pour ajouter des données et faire des calculs.

    Mon soucis arrive au moment ou je veux vérifier la présence ou non de doublons dans la BDD et les supprimer si il y en a.
    En fait il n'y a pas de clé unique dans les imports.
    De nombreuses valeurs peuvent se trouver en communs de différentes lignes.

    Je voudrais donc supprimer les lignes TOTALEMENT identiques (sur 164 colonnes).

    Que me conseillez vous afin de perdre le moins de temps possible et évidement d'obtenir un fichier propre ?

    Voilà ce que j'ai tenté sans succès :

    //On copie toutes les valeurs trouver dans la requête - la requête copie toutes les valeurs mais supprime les doublons
    HExécuteRequête(REQ_BaseSansDoublons)

    // On efface toute la BDD "BaseCopie" et on y intègre la requête sans doublons pour effacer les doublons si il y a eu plusieurs imports des mêmes données
    HCréation(BaseCopie)

    //Maintenant on ajoute les données dans le fichier "BaseCopie"
    HLitPremier (REQ_BaseSansDoublons) // Charge en mémoire les données du premier enregistrement du fichier

    TANTQUE PAS HEnDehors(REQ_BaseSansDoublons)

    //Il faut copier toutes les valeurs !!! ICI LA COPIE fonctionne mais je n'obtiens que des 0 et seulement pourcertaines colonnes ...
    HCopieEnreg(BaseCopie,REQ_BaseSansDoublons,hValDéfaut)

    HRAZ(BaseCopie)
    HAjoute(BaseCopie)

    HLitSuivant (REQ_BaseSansDoublons)
    TableAffiche(TABLE_BaseCopie,taInit)

    FIN

    //On efface la BDD de Base
    HCréation(Base)

    //Maintenant on ajoute les données
    HLitPremier (BaseCopie) // Charge en mémoire les données du premier enregistrement du fichier

    TANTQUE PAS HEnDehors(BaseCopie)

    HCopieEnreg(Base,BaseCopie)

    HRAZ(Base)
    HAjoute(Base)

    HLitSuivant (BaseCopie)

    TableAffiche(TABLE_Base,taInit)

    FIN
    Merci d'avance pour votre aide qui est toujours très précieuse.

    Justine.

  2. #2
    Membre très actif Avatar de PaulNero
    Homme Profil pro
    DBA Senior Oracle and SQL SERVER
    Inscrit en
    Octobre 2010
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Inde

    Informations professionnelles :
    Activité : DBA Senior Oracle and SQL SERVER
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2010
    Messages : 416
    Par défaut
    Bonsoir,
    si j'étais vous je créerai une procédure qui s'appellerait doublonTraitement qui parcourirait l'ensemble des "fichiers" de la base avec chaque rubrique , et ce grace à la fonction HGEREDOUBLON.
    Cela peut prendre du temps, mais une fois la procédure est lancée, vous êtes sur qu'après son exécution, vous viendrez à bout des doublons.


    cordialement++

  3. #3
    Membre actif Avatar de NetLandGim
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations forums :
    Inscription : Mars 2011
    Messages : 97
    Par défaut DOUBLON?
    Tes doublons portent sur quoi
    Dans une base relationnelle, un doublon portent sur des colonnes ou des couples de colonnes.
    N'oublie pas de fixer des contraintes d'unicités sur la BDD.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 80
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    En fait si j'ai tenté de faire cette manipulation qui n'est pas très "propre c'est que j'ai tenté de créer une clé composée (sur 22 colonnes).

    Je n'arrive ni :
    à la voir (lorsque je fais l'intgration de mon fichier csv toutes la colonne cléComp est vide)
    à la faire fonctionner (les doublons sont tous intégrés si la clé composée et clé avec doublon et 1 seule ligne est intgrée avant erreur si la clé est clé unique).

    Donc j'en conclu que toutes les valeurs de cette clés doivent être nulles ...

    PaulNero, je vais intégrer à chaque fois plusieurs milliers de lignes, faire une procédure qui contrôle tout ne va pas vraiment ralentir l'appli ?

    Je doit construire un Trigger ?

    J'ai aussi essayé en intégrant ce code à la fin de ma boucle :
    HGèreDoublon(Base,CleComp,Vrai)
    //HAjoute(bASE)
    SI HAjoute(Base) = Faux ALORS
    SI HErreurDoublon() = Vrai ALORS
    sNomRub est une chaîne
    sNomRub = HErreurInfo(hErrRubrique)
    Erreur("Doublon : cet enregistrement ne peut pas être ajouté", ...
    "Rubrique associée à l'erreur : "+ sNomRub, ...
    FIN
    FIN
    Mais si j'intègre 2 fois le même fichier rien ne se passe, je me retrouve avec le fichier en double dans ma base...

    Merci pour votre aide.

  5. #5
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 229
    Par défaut
    bonjour,
    excuses moi JustineJ mais j'ai supprimé mon message car je me suis aperçu que en effet avec un identifiant automatique tu as toujours tes doublons possibles.
    Pour la clécomposée as-tu essayé un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    sCleComposee est une chaine
    // valchamp valeurs des champs qui servent de clé composée
    sClecomposee = valchamp1 + valchamp2 + ... + valchampx
    HLitRecherche(MonFichier,CLECOMPOSEE,sClecomposee)
    SI PAS HTrouve(Monfichier) ALORS 
    // on ajoute l'enregistrement
    Ami calmant, J.P ;-)

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 80
    Par défaut
    Merci Jurassic Pork,

    Je viens d'essayer ça, ça fonctionne à peu près.
    Le problème viens juste des colonnes que je choisi pour faire la clé composée, elles ne semblent pas complètes puisque je retrouve des doublons...

    Bref, il faut que j'affine ma clé composée mais le principe marche nickel.

    Encore merci !

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 80
    Par défaut
    Re bonjour à tous,

    Je tente de mettre en pratique vos conseils mais suis bloquée sur certains points.
    Le premier problème est que je souhaite tester le fichier sur plusieurs colonnes qui ne sont pas des clés.

    1)Ma 1ère tentative a donc été de créer une clé composée dans mon fichier.
    Lorsque cette clé est "avec doublons" les doublons ne sont pas repérés.
    Par contre si je la met en "clé unique" les enregistrements ne sont pas possibles dès qu'une seule ligne a été intégrée. Toutes les clé composées sont alors considérées comme doublons ...

    2)Deuxième tentative : lors de l'import du fichier et juste avant le HAjoute
    Cle est une chaîne
    // valchamp valeurs des champs qui servent de clé composée
    sCle = Val1+Val2+Val3+sVal4+Val5+Val6+Val7+Val8+Val9+Val10+Val11+Val12+Val13+sVal14+Val15+Val16+Val17+Val18+sVal19+Val20+val21+sVal22

    HLitRecherche(Base,CléComposée,sCle)

    SI HTrouve(Base)=Faux ALORS
    // on ajoute l'enregistrement
    HAjoute(Base)
    SINON
    CompteDoublons=CompteDoublons+1
    FIN
    HRAZ(Base)


    CompteDoublons est un entier=0
    j est un entier=0
    i est un entier=0
    nNombreLigne est un entier =TABLE_Base..Occurrence
    NombreLigne2 est un entier=nNombreLigne-1

    //HLitPremier(Base,CléComposée)
    POUR j=1 A NombreLigne2//(nNombreLigne-1)
    CléBase est une chaîne=Base.CléComposée[j]

    //CléBase est une chaine=base.CléComposée
    //nIndiceDébut est un entier =dbgLigne

    POUR i=(j+1) A nNombreLigne
    CléComparée est un entier =Base.CléComposée[i]

    SI CléComparée=CléBase ALORS
    TableSupprime(TABLE_Base,i)
    //HSupprime(Base,i)
    CompteDoublons=CompteDoublons+1
    nNombreLigne=nNombreLigne-1
    SINON
    i=i+1
    FIN
    FIN
    j=j+1
    FIN

    //HLitsuivant(Base,CléComposée)

    LIB_Libellé3=CompteDoublons+" enregistrements supprimés"
    Ce code fonctionne pour supprimer les doublons du fichier que l'on est en train d'intégrer.
    Par contre il ne fait pas de test avec les valeurs qui sont déjà dans le HF et je ne vois absolument pas pourquoi.

    3)Je fais un code séparé qui test toutes les lignes du fichier HF et qui supprime les doublons trouvés :

    CompteDoublons est un entier=0
    j est un entier=0
    i est un entier=0
    nNombreLigne est un entier =TABLE_Base..Occurrence
    NombreLigne2 est un entier=nNombreLigne-1

    //HLitPremier(Base,CléComposée)
    POUR j=1 A NombreLigne2//(nNombreLigne-1)
    CléBase est une chaîne=Base.CléComposée[j]

    //CléBase est une chaine=base.CléComposée
    //nIndiceDébut est un entier =dbgLigne

    POUR i=(j+1) A nNombreLigne
    CléComparée est un entier =Base.CléComposée[i]

    SI CléComparée=CléBase ALORS
    TableSupprime(TABLE_Base,i)
    //HSupprime(Base,i)
    CompteDoublons=CompteDoublons+1
    nNombreLigne=nNombreLigne-1
    SINON
    i=i+1
    FIN
    FIN
    j=j+1
    FIN

    //HLitsuivant(Base,CléComposée)

    LIB_Libellé3=CompteDoublons+" enregistrements supprimés"
    Cette fois-ci j'ai un problème avec mon code qui est très probablement faux mais que je n'arrive pas à corriger ...

    Erreur à la ligne 16 du traitement Clic sur BTN_SansNom5.
    L'indice <2> n'est pas un indice valide pour la rubrique <Base.CléComposée>.
    Ce qui me semble idéal est la méthode 2).
    Cependant je suis ouverte à toutes vos propositions et corrections.
    Je m'acharne sur ce code depuis plusieurs jours et commence à être un peu désespérée ...

    Merci d'avance.

  8. #8
    Membre actif Avatar de NetLandGim
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations forums :
    Inscription : Mars 2011
    Messages : 97
    Par défaut Trop de colonnes dans tes tables
    Une base de données relationnelles est là pour des relations et non uniquement pour stocker des fichiers.

    Essaie de créer un fonction qui va gérer ça sur le serveur.
    Voilà par exemple un trigger que j'ai créer pour refuser des doublons de personnes dans une base de données PostgreSQL écrites en PLPGSQL et que j'utilise dans une application WIndev.
    La fonction rejette toutes les valeurs en double.
    Pour l'adapter à ton cas, le trigger renverrait NULL si doublon et NEW.* si distinct
    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
     
    CREATE OR REPLACE FUNCTION f_doublon_personne()
      RETURNS TRIGGER AS
    $BODY$
    DECLARE
    i INTEGER;
    BEGIN
    	SELECT c_idpersonne FROM personne 
    	WHERE upper(c_nom)=upper(NEW.c_nom) AND upper(c_prenoms)=upper(NEW.c_prenoms)
    	AND c_datenaissance=NEW.c_datenaissance AND c_sexe=NEW.c_sexe 
    	AND upper(c_pere)=upper(NEW.c_pere) AND upper(c_mere)=upper(NEW.c_mere) AND upper(c_lieunaissance)=upper(NEW.c_lieunaissance) 
    	INTO i;
     
    	IF  FOUND THEN
     
    		IF (TG_OP='INSERT') THEN
    		RAISE EXCEPTION 'Doublon identitaire non autorisé!';
    		END IF;
     
    		IF (TG_OP='UPDATE') THEN
    				IF i<> OLD.c_idpersonne THEN
    				RAISE EXCEPTION 'Doublon identitaire non autorisé!';
    				END IF;
    		END IF;
     
    	ELSE
    	RAISE NOTICE 'Doublon non détecté';
     
    	END IF;
     
    RETURN NEW;
     
     
    END $BODY$
      LANGUAGE 'plpgsql';

  9. #9
    Membre actif Avatar de NetLandGim
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations forums :
    Inscription : Mars 2011
    Messages : 97
    Par défaut TRIGGER
    Ainsi au lieu de lever une exception en cas de doublon, on ne fait et on passe à une autre insertion.

    Autre conseil, NE PAS ABUSER SUR L UTILISATION DES INDEX

    CONSEILLE D UTILISER UN TRIGGER POUR FILTRER TES DOUBLONS!

  10. #10
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 229
    Par défaut
    Bonjour,
    Mon code sur la recherche par clé composée n'est pas correcte si il y a des numériques,des dates dans les rubriques. Il faudrait plutôt faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    HLitRecherche(Base,CléComposée,[Val1,Val2,Val3,sVal4,Val5,Val6,Val7,Val8,... 
    Val9,Val10,Val11,Val12,Val13,sVal14,Val15,Val16,Val17,Val18,... 
    sVal19,Val20,val21,sVal22])
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sCle est une chaîne
    sCle = HConstruitValClé(Base,CléComposée,Val1,Val2,Val3,sVal4,Val5,... 
    Val6,Val7,Val8,Val9,Val10,Val11,Val12,Val13,sVal14,Val15,Val16,Val17,... 
    Val18,sVal19,Val20,val21,sVal22)
    HLitRecherche(Base,CléComposée,sCle)
    Les 2 sont équivalents.

    En ce qui concerne ton problème sur les doublons si tu mets ta clé composée en clé unique c'est peut-être cela ( vu sur un autre forum) :
    Contrairement aux autres langages dont j'avais l'habitude, les clés
    composées uniques renvoient une erreur de doublon si UN des éléments est
    susceptible de créer un doublon sur l'ensemble des clés composées

    exemple:

    aaaaaaa,1234
    aaaaaaa,4321
    bbbbbbb,1234 =>>>>>>>> erreur doublon
    ccccccc,5678
    aaaaaaa,5678 =>>>>>>>> erreur doublon aussi

    vicieux, comme piège!
    Avis à ceux qui ne sont pas encore tombé dedans!
    Si quelqu'un pouvait confirmer ?

    Ami calmant, J.P

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 80
    Par défaut
    Bonjour et merci,

    Alors j'ai tenté un Trigger avant HAjoute:

    PROCEDURE Test_Doublons()

    CompteurDoublons est un entier=0

    HLitPremier(Base,CléComposée)
    SI Base.CléComposée=clé ALORS
    CompteurDoublons=CompteurDoublons+1

    SINON


    FIN
    HSuivant(Base,CléComposée)
    Mais forcément, il ne connaît pas "Clé" qui est calculé dans ma procédure de base...

  12. #12
    Membre éclairé Avatar de J0r_x
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2006
    Messages
    804
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2006
    Messages : 804
    Par défaut
    Après l'import et avant le traitement, tu fais un requête qui supprime les doublons, tu les récupères avec un GROUP BY & HAVING COUNT(*) > 1, pour toutes les lignes retournées, tu les supprimes puis tu les ajoutes, et tu n'as plus de doublons.

Discussions similaires

  1. [Source] Trieur de Doublons, BDD Access / Excel
    Par mortalino dans le forum Vos contributions VB6
    Réponses: 5
    Dernier message: 23/03/2007, 16h37
  2. Trigger pour suppression doublons ds table
    Par lg_gaelle dans le forum PL/SQL
    Réponses: 2
    Dernier message: 18/10/2006, 15h53
  3. Suppression doublon Table
    Par francois78 dans le forum Access
    Réponses: 11
    Dernier message: 13/06/2006, 16h16
  4. Suppression doublons
    Par osmoze dans le forum Oracle
    Réponses: 2
    Dernier message: 26/04/2006, 13h17
  5. [MySQL] Problème de syntaxe dans suppression doublons
    Par fred23195 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 13/04/2006, 15h45

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