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

SGBD Perl Discussion :

problème de remplissage de table


Sujet :

SGBD Perl

  1. #1
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut problème de remplissage de table
    Bonjour,


    J'ai un problème avec le script suivant :


    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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # récupération de l'id clé primaire de la table fungi2 ainsi que du champ accession
    my $sql0 = "SELECT id, accession FROM fungi2";
    my $sth0 = $dbh->prepare($sql0) or print "erreur de preparation SQL\n";
    $sth0->execute or die "Could not execute SQL statement ... maybe invalid?";
     
     
    while (my @row = $sth0->fetchrow_array){
     
    	my $ID = $row[0];
    	my $ACC = $row[1];
     
    	# séparation des accessions
    	my @acc_list = split (/ /, $ACC);
     
    	for my $i (0...$#acc_list){
     
    		# 1 accesion = 1 entrée de la table fungi2_accessions
    		# clé primaire de fungi2_consensus = nombre autoincrémenté (num)
    		# champ id de fungi2_consensus = FK liée à PK id de fungi2
    		my $sql1 = "INSERT INTO fungi2_accessions VALUES ('', '$ID', '$acc_list[$i]')";
    		my $sth1 = $dbh->prepare($sql1) or print "erreur de preparation SQL\n";
    		$sth1->execute or die "Could not execute SQL statement ... maybe invalid?";
    		$sth1->finish;
    	}
     
    }
    $sth0->finish;

    Lors du remplissage, voici l'erreur qui apparait :
    mysql::st execute failed: Duplicata du champ '32767' pour la clef 1 at rempissage_fungi2_accessions.pl line 42.
    Could not execute SQL statement ... maybe invalid? at rempissage_fungi2_accessions.pl line 42.

    Aperçu des 2 tables




    Problème

    Pour l'id 32767 qui n'a qu'un accession dans la table fungi2 et ne devrait donc n'avoir qu'une seule entrée dans fungi2_accessions, le script en crée 2138. Ce qui est étrange, c'est que tout se passe bien lors du remplissage des premières entrées. (cf image)


    Une autre remarque mais pas vraiment dérangeante est qu'il commence le remplissage de fungi2_accessions avec un 'Num' à 5 au lieu de 1 (pour le premier id '1')... alors que Num est de type SMALLINT(3) NOT NULL AUTOINCREMENT.


    Merci pour votre aide,
    -- Jasmine --

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    voici ton script remodelé
    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
    # récupération de l'id clé primaire de la table fungi2 ainsi que du champ accession
    my $sql0 = "SELECT id, accession FROM fungi2";
    my $sth0 = $dbh->prepare($sql0) or print "erreur de preparation SQL\n";
    $sth0->execute or die "Could not execute SQL statement ... maybe invalid?\nSELECT : $sql0\n";
     
     
    while ( my @row = $sth0->fetchrow_array ) {
     
    	my $ID = $row[0];
    	my $ACC = $row[1];
     
    	# séparation des accessions
    	my @acc_list = split (/ /, $ACC);
     
    	my $sql1 = "INSERT INTO fungi2_accessions VALUES (?, ?,?)";
    	my $sth1 = $dbh->prepare($sql1) or print "erreur de preparation SQL\n";
    	for my $i (0...$#acc_list){
     
    		# 1 accesion = 1 entrée de la table fungi2_accessions
    		# clé primaire de fungi2_consensus = nombre autoincrémenté (num)
    		# champ id de fungi2_consensus = FK liée à PK id de fungi2
    		$sth1->execute("NULL", $ID, $acc_list[$i]) or die "Could not execute SQL statement ... maybe invalid?\nINSERT : $ID, $acc_list[$i]\n";
    	}
     
    }
    $sth0->finish;
    Je te conseil maintenant, si possible de vider tes tables.
    De remettre les auto incrémentation à 0 ainsi :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE fungi2_accessions AUTO_INCREMENT=0;
    ALTER TABLE fungi2 AUTO_INCREMENT=0;

    Et de relancer ton script et voir le résultat.

    Peux tu nous montrer la structure des deux tables? Es tu sûr que les champs id sont uniques?

  3. #3
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Merci pour ton aide.

    Voici la dernière version de mon script mais je vais voir si je peux l'améliorer avec le tien. Mes id sont bien uniques (ce sont d'ailleurs les clés primaires de Fungi2).
    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
    # récupération de l'id clé primaire de la table fungi2 ainsi que du champ accession
    my $sql0 = "SELECT id, accession FROM fungi2";
    my $sth0 = $dbh->prepare($sql0) or print "erreur de preparation SQL \$sql0\n";
    $sth0->execute or die "Could not execute SQL statement ... maybe invalid?";
     
     
    # suppression de la table fungi2_consensus
    $dbh->do("DROP TABLE IF EXISTS fungi2_accessions;")
        or die "Impossible de supprimer la table fungi2_accession\n\n";
     
    # création de la table fungi2_consensus
    my $SQLCreationTables = <<"SQL";
    CREATE TABLE fungi2_accessions(
    Num SMALLINT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    id INT(6) NOT NULL ,
    Accession VARCHAR( 20 ) NOT NULL 
    ) ENGINE = InnoDB
    SQL
     
    $dbh->do($SQLCreationTables)
        or die "Impossible de creer la table fungi2_accessions\n\n";
     
     
    while (my @row = $sth0->fetchrow_array){
     
    	my $ID = $row[0];
    	my $ACC = $row[1];
     
    	# séparation des accessions
    	my @acc_list = split (/ /, $ACC);
     
    	# print "=> $ID\n$ACC\n$#acc_list\n";
     
    	for my $i (0...$#acc_list){
     
    		# 1 accesion = 1 entrée de la table fungi2_accessions
    		# clé primaire de fungi2_consensus = nombre autoincrémenté (num)
    		# champ id de fungi2_consensus = FK liée à PK id de fungi2
    		my $sql2 = "INSERT INTO fungi2_accessions VALUES ('', '$ID', '$acc_list[$i]')";
    		my $sth2 = $dbh->prepare($sql2) or print "erreur de preparation SQL \$sql2\n";
    		$sth2->execute or die "Could not execute SQL statement ... maybe invalid?";
    		$sth2->finish;
    	}
     
    }
    $sth0->finish;
     
     
     
     
    # Déconnection à la base de données
    $dbh->disconnect();
    J'ai essayé la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id, accession FROM fungi2 WHERE id > 32766 AND id < 32770
    résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          1 32767 EF641303 
          2 32767 AB051649 
          3 32767 EU057060

    Je pensais avoir trouvé le problème, mon champ id de la table fungi2_consensus était un SMALLINT ... je l'ai remplacé par INT.


    Avec id mis à INT( 5 )

    le résultat de la même requête est correct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          1 32767 EF641303 
          2 32768 AB051649 
          3 32769 EU057060

    Mais si je recommence avec l'entièreté de Fungi2, ça recoince à 32767 avec le même message d'erreur ... étrange.

    Le problème doit venir du type de variable ou d'un problème de saturation.
    ... je vais déjà rajouter UNSIGNED pour les valeurs numériques.


    Merci pour le script.
    -- Jasmine --

  4. #4
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Structure de Fungi2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE `test`.`fungi2` (
    `Id` int( 3 ) NOT NULL AUTO_INCREMENT ,
    `Organism` varchar( 50 ) default NULL ,
    `Taxon` smallint( 10 ) default NULL ,
    `Accession` text,
    `Longueur` smallint( 5 ) default NULL ,
    `Sequence` longtext,
    `Date` date default NULL ,
    PRIMARY KEY ( `Id` ) ,
    KEY `Organism` ( `Organism` ) 
    ) ENGINE = InnoDB DEFAULT CHARSET = latin1;
    -- Jasmine --

  5. #5
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Manuel MySQL


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Type 		Octets 	De 			A
    TINYINT 	1 	-128 			127
    SMALLINT 	2 	-32768 			32767
    MEDIUMINT 	3 	-8388608 		8388607
    INT 		4 	-2147483648 		2147483647
    BIGINT 		8 	-9223372036854775808 	9223372036854775807
    ... et voila, SMALLINT sur 2 octet de -32768 à 32767 ... donc un SMALLINT UNSIGNED aura une zone de 0 à 65534 ce qui devrait me suffire.
    -- Jasmine --

  6. #6
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Mets tout à INT, pas besoin de se prendre le chou

  7. #7
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Citation Envoyé par djibril Voir le message
    Mets tout à INT, pas besoin de se prendre le chou
    La perfection serait-elle donc vraiment l'ennemi du bien, comme ma grand-mère me l'a plusieurs fois répété?
    Il est vrai que si j'avais mis INT partout sans me poser de question, je n'aurais jamais eu se problème .

    Dernière entrée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	my $sql1 = "INSERT INTO fungi2_accessions VALUES (?, ?,?)";
    	my $sth1 = $dbh->prepare($sql1) or print "erreur de preparation SQL\n";
    	for my $i (0...$#acc_list){
     
    		# 1 accesion = 1 entrée de la table fungi2_accessions
    		# clé primaire de fungi2_consensus = nombre autoincrémenté (num)
    		# champ id de fungi2_consensus = FK liée à PK id de fungi2
    		$sth1->execute("NULL", $ID, $acc_list[$i]) or die "Could not execute SQL statement ... maybe invalid?\nINSERT : $ID, $acc_list[$i]\n";
    	}
    A oui, ce sont les fameux placeholders ... ça me rappelle d'ailleurs que je n'ai pas fini de lire ton article sur DBI mais 2 projets viennent de me tomber dessus, je suis un peu débordée en ce moment.

    ... je retiens pour la prochaine fois, maintenant que la table est ENFIN faite et faite correctement, je n'y touche plus sauf pour créer mes clés étrangères.


    Merci pour tes conseils,
    -- Jasmine --

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

Discussions similaires

  1. [MySQL] problème de remplissage de table (delay ?)
    Par allbundy dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 04/04/2012, 09h58
  2. Réponses: 2
    Dernier message: 27/03/2008, 15h59
  3. Réponses: 4
    Dernier message: 29/06/2007, 16h08
  4. [Excel_VBA]2 problèmes avec remplissage de la table
    Par tangjuncn dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 15/02/2007, 09h57
  5. Problème d'ordre de remplissage de table
    Par matana dans le forum Langage SQL
    Réponses: 6
    Dernier message: 24/03/2006, 16h37

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