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

MySQL Discussion :

Champ unique mais vide au démarrage : Duplicate Entry [MySQL-5.0]


Sujet :

MySQL

  1. #1
    Membre éclairé
    Homme Profil pro
    Programmeur fou
    Inscrit en
    Octobre 2010
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Programmeur fou

    Informations forums :
    Inscription : Octobre 2010
    Messages : 363
    Par défaut Champ unique mais vide au démarrage : Duplicate Entry
    Bonjour à tous,

    J'ai un champ SIRET vide déclaré en varchar(9) sans valeur par défaut, dans une table de 50 magasins sans SIRET.
    Je souhaite qu'il soit unique pour détecter les doublons à la mise à jour de ma table, je précise donc dans phpMyAdmin "Unique" et il me dit "Duplicate Entry".
    J'ai essayé de mettre NULL comme valeur par défaut, pareil.
    Comment permettre que tous les champs SIRET de ma table soient vides ET uniques, pour pouvoir modifier ma table magasin par magasin en contrôlant (ERR 1062) que l'utilisateur ne rentre pas deux fois le même SIRET, svp ?
    Merci.

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    Bonjour,

    cf la doc : http://dev.mysql.com/doc/refman/5.5/...ate-table.html


    A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. For all engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL.

    Vous avez donc déjà des doublons de siret dans votre table, qui sont différent de "null".

  3. #3
    Membre éclairé
    Homme Profil pro
    Programmeur fou
    Inscrit en
    Octobre 2010
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Programmeur fou

    Informations forums :
    Inscription : Octobre 2010
    Messages : 363
    Par défaut
    Ca c'est une bonne piste.
    Je contrôle. Merci.

    EDIT : j'ai supprimé le champ, je l'ai recréé NULL UNIQUE et ça a marché. je suppose que je mettais un ou plusieurs espaces dedans à un moment de mes tests.

  4. #4
    Membre éclairé
    Homme Profil pro
    Programmeur fou
    Inscrit en
    Octobre 2010
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Programmeur fou

    Informations forums :
    Inscription : Octobre 2010
    Messages : 363
    Par défaut
    Hmmm... je rencontre un nouveau problème sur le même sujet, c'est pourquoi je n'ouvre pas un nouveau sujet.

    Ma table contient aujourd'hui 50 magasins avec 50 SIRET différents. So far so good comme disait Laetizia Buonaparte.
    Si j'ai une nouvelle création de magasin et que l'utilisateur ne met pas son SIRET, le champ est NULL comme avant. Ca colle (à moi de l'accepter ou non).
    Mais si j'en crée un 2e, toujours sans SIRET, MySQL se plaint d'une clé dupliquée valeur nulle alors que je n'ai PAS changé la table.
    Pourqoi, à votre avis, svp ?
    Merci.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Toulousaing Voir le message
    Mais si j'en crée un 2e, toujours sans SIRET, MySQL se plaint d'une clé dupliquée valeur nulle alors que je n'ai PAS changé la table.
    Pourqoi, à votre avis, svp ?
    Parce que MySQL est farci de tares de bugs et de bêtises et qu'il croit naïvement que quelque chose qui n'existe pas (NULL) peut être dupliqué; C'est une des nombreuses erreurs de conception de cet ersatz de SGBDR !

    A lire sur le sujet : http://blog.developpez.com/sqlpro/p9...oudre_aux_yeux

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Parce que MySQL est farci de tares de bugs et de bêtises et qu'il croit naïvement que quelque chose qui n'existe pas (NULL) peut être dupliqué
    Non, en l’occurrence, c'est un comportement propre à SQL Server, et normalement, MySQL ne commet pas cette erreur.

    Pouvez-vous nous fournir plus de détail ? script de création de la table et de l'index unique, et script d'insertion des lignes "dupliquées" ?
    Ainsi que le message d'erreur exact.

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    La plupart du temps c'est parce que MySQL remplace les NULLs par des chaines vides (tare congénitale !)

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Petit test...

    Création d'une table avec une colonne nullable et munie d'un index UNIQUE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE `test_null_unique` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `col_texte` varchar(20) NOT NULL,
     `col_nullable` varchar(20) DEFAULT NULL,
     PRIMARY KEY (`id`),
     UNIQUE KEY `col_nullable` (`col_nullable`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    => OK

    Insertion d'une première ligne en spécifiant NULL pour la colonne nullable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO `test`.`test_null_unique` (`id`, `col_texte`, `col_nullable`) VALUES (NULL, 'toto', NULL);
    => OK

    Vérification :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM `test_null_unique`
    => 1, 'toto', NULL
    C'est OK et on remarque que comme la première colonne est en auto-incrément, l'insertion d'un NULL entraîne la création de l'id automatiquement.

    Insertion d'une deuxième ligne sans spécifier de valeur pour la colonne nullable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO test_null_unique(col_texte)
    VALUES('titi')
    => OK

    Vérification :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM `test_null_unique`
    =>
    1, 'toto', NULL
    2, 'titi', NULL

    On voit bien qu'il y a deux fois NULL et que l'index UNIQUE n'est pas violé, ce qui est normal parce que NULL est un marqueur et non pas une valeur. Et tous les NULL sont considérés comme différents.

    Conclusion : Êtes-vous bien sûr d'insérer le marqueur NULL et non pas la chaîne de caractères 'NULL' ou une chaîne vide dans votre colonne UNIQUE ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre éclairé
    Homme Profil pro
    Programmeur fou
    Inscrit en
    Octobre 2010
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Programmeur fou

    Informations forums :
    Inscription : Octobre 2010
    Messages : 363
    Par défaut
    Je pense que j'insère une chaîne vide vu que mon SIRET vient d'un POST :

    Code php : 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
    $siret = $_POST['siret'];
     
    // We connect to the MySQL server
    $db_server = "mysql.xxxxxxx.fr";
    $db_user = "yyyyyyyyyyyyyy";
    $db_pwd = "zzzzzzzzzzzzzzzz";
    $conn = @mysql_connect($db_server, $db_user, $db_pwd) or die ("<p><b>ERR 1 : La connexion au serveur a échoué.</b>");
     
    // We connect to the database
    $db_base = "mybase";
    $rs = @mysql_select_db($db_base, $conn) or die ("<p><b>ERR 2 : La connexion à la base de données a échoué.</b>");
     
    mysql_query("SET NAMES 'utf8'");
     
    // record request
    $sql = "insert into members (last_name,first_name,email,address_1,address_2,postal_code,city,country,birth_date,team_leader_email,code,rank,bx_reg_date,shop,siret)
    		values ('$last_name','$first_name','$email','$address_1','$address_2','$postal_code','$city','$country','$birth_date','$team_leader_email','$code','$rank','$bx_reg_date','$shop','$siret')";
     
    // we execute the request
    if (!$rs = @mysql_query($sql, $conn))
    {
    	if (mysql_errno() == "1062")
    	{
    		echo "<p><b>Un membre avec cette adresse eMail existe déjà.</b>";
    		exit;
    	}
    	else
    	{
    		echo "<p><b>ERR 3 : Erreur SQL au moment de l'insertion.</b>";
    		echo "<br>SQL Error: " . mysql_errno() . " " . mysql_error();
    		exit;
    	}
    }

  10. #10
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Ben voilà !
    En plus avec votre programme, vous n'êtes pas à l'abri des injections SQL !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Membre éclairé
    Homme Profil pro
    Programmeur fou
    Inscrit en
    Octobre 2010
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Programmeur fou

    Informations forums :
    Inscription : Octobre 2010
    Messages : 363
    Par défaut
    Oui, c'est vrai mais ce code est dans une zone protégée, un espace membres, donc j'ose supposer que "mes" membres ne vont pas installer metasploit pour m'emm... vous voyez :-)

    Merci à tous pour l'aide.
    Je rajoute un if (!$siret) $siret= NULL;
    Promis.

    Bye.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/04/2015, 12h00
  2. [WD16] Affectation d'un champ table mais vide
    Par Marcuss57 dans le forum WinDev
    Réponses: 2
    Dernier message: 23/02/2015, 17h11
  3. [MySQL] duplicate entry avec unique
    Par djoumusic dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 07/07/2008, 20h03
  4. Réponses: 8
    Dernier message: 23/01/2008, 22h59
  5. Ne pas afficher un champs qui est vide dans ma BD
    Par yoda_style dans le forum ASP
    Réponses: 3
    Dernier message: 27/04/2004, 11h40

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