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

PHP & Base de données Discussion :

Requêtes sur une table des départements français [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut Requêtes sur une table des départements français
    Bonsoir,

    je dois faire un formulaire avec comme base de recherche le département, ensuite je propose les villes.

    le problème :

    certains départements de ma base sont en 4 chiffres, en fait tous les numéros commençant par 0..

    1ere solution )
    je voudrais faire un update de mes lignes dans le cas ou le strlen d'une valeur est égale à 4

    Par exemple sur une ligne le département vaut 2220, il faut que je le remplace en 02220;

    Je n'ai aucune idée de la meilleurs requête en Mysql.


    2eme solution )
    Cependant, il est peu être possible de ne pas changer les valeurs de la base de données, mais de créer une requête de recherche adéquate.


    Merci d'avance de vos conseils.
    Images attachées Images attachées  
    Conception / Dev

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    Bon je l'ai fait comme ca :

    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
     
     
    $bdd = new mysqlPdo;
     
    $query=" SELECT code_postal,id FROM `pjr_carte` WHERE CHAR_LENGTH(code_postal)=4  ";
     
    $liste =  $bdd->query($query,array());
     
      for ($i = 0 ; $i < count ($liste ) ; $i++ ){
     
      $cp = '0'.$liste[$i]->code_postal;
      $id = $liste[$i]->id;
     
      $updateQuery=  "UPDATE pjr_carte SET code_postal =:cp WHERE id =:id";
          try{
          $bdd->query($updateQuery,array('code_postal'=>$cp,'id'=>$id));
          }catch (Exception $e) {
          JUSC_Exception::message('Message erreur  : '.$e);		
          }
     
     
      }

    mais je pense que j'aurais pu directement le faire en mysql..

    a voir, je mets résolu si pas de réponse

    En plus

    Pour ceux qui peuvent être intéressé par la construction de la Class mysqlPdo, inspiré pour l'instant de Benjamin et du site officiel de php, ascito propose un code minimal en vue d'amélioration collectives mais surtout au rendu facile à lire....

    Les mots d'ordre : Efficacité, sécurité, lisibilité, et compréhension



    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    <?php
    class bdd extends PDO 
    {
    final public function __construct($dsn, $username = '', $password = '', $driverOptions = array())
        {
            $driverOptions += array(self::ATTR_ERRMODE => self::ERRMODE_EXCEPTION,
    	self::ATTR_STATEMENT_CLASS => array('Statement'));
            parent::__construct($dsn, $username, $password, $driverOptions);
        }
    }
    class Statement extends PDOStatement 
    {
     
    }
     
    abstract class _mysqlPdo
    {
     
        public function result($array)
        {
            return $array;
        }
     
        protected  function connect()
        {
            try {
            $dbh = new bdd('mysql:host=localhost;dbname=mabdd', 'root','motdepasse');
    	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            }
            catch (PDOException $e) {
            throw new Exception("Error occured while saving your object", null, $e);
            }
            return $dbh;
        }
     
        private function _bindParam($sth,$array){
     
        }   
        private function _prepare(){
     
        }
        private function _execute(){
     
        }
        protected  function _query($query,$array )
        {
     
            $id=0;
            $dbh = $this->connect();
            if($query==='' || $query===$this->curentQuery ){
                $sth = $this->curentQuery;
            }else{
                $sth = $dbh->prepare($query);
                $this->curentQuery = $sth;
            }
    	    if(!empty($array)){
    		foreach($array as $key =>$v ){
    		$sth->bindValue( ':'.$key ,$v);
    		}		
    	    }
             try {
     
            $sth->execute();
     
    	if(substr_count($sth->queryString,'SELECT')>0)
    	    {
    	    return $this->result($sth->fetchAll(PDO::FETCH_CLASS,'mysqlPdo'));
    	    }
    	    else{
    	    return true;
    	    }
            }
            catch (PDOException $e) {
    	    JUSC_Exception::message( $e->getMessage());		
     
            }  
     
        }
     
        abstract public function query($query,$array );
     
        }
     
        class mysqlPdo extends _mysqlPdo
        {
     
    	   public function query($query,$array )
    	   {
    	    return $this->_query($query,$array );
    	   }
     
        }
     
     
     
    ?>
    Conception / Dev

  3. #3
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    A moins que je ne me trompe, il manque des accolades dans ton code.

    Mais je m'interroge surtout de la pertinence de ces classes, qu'est-ce qu'elles apportent comme valeur ajoutée ?

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    non pour les accolades c'est OK;

    Pour ma part j'utilise mysql depuis que j'ai commencé à bosser avec php...

    Je trouve assez intéressant et rapide d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $id=10;
    $db = new mysqlPdo;
    $result  = $db->query ( 'SELECT count (id) FROM maTable WHERE id = :id ', Array('id'=>$id)) ;
    print_r($result);
    Avec PDO il est possible d’intégrer le fait que $id soit typé, et aussi il y a une gestion des drivers..

    On peu choisir le type de réponse que l'on attends, pour ma part je suis foreach et While ( fetch ) et aussi possible

    ( les class bdd,mysqlPdo etc doivent tenir en peu de place [sans l'appel au fichier config qui donne les logs, plus sécurisé] )

    Donc le résultat de la class mysqlPdo devra pouvoir faciliter la vie de tout le monde, avoir une base cohérente et lisible ( pour la partie sécurité je me base plus sur ton boulot qd même, création des class etc), être paramétrable uniquement par un seul appel, et encore une fois avoir un résultat de retour qui sera facile à comprendre selon les habitude :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $db = new mysqlPdo;
    $id = 11;
    $query[0] =  'SELECT count (id) FROM maTable WHERE id = :id ';
    $result  = $db->query ( $query[0] , Array('id'=>$id),'object') ;
    print_r($result);
    finalement abstraire la class PDO ( en vue des utilisateurs SQL pour ma part) , avec les composant les plus utiles et les rendre humainement compréhensible

    franchement
    Conception / Dev

  5. #5
    Membre éprouvé Avatar de redoran
    Homme Profil pro
    Développeur-Amateur
    Inscrit en
    Juin 2010
    Messages
    1 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur-Amateur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 346
    Points : 1 031
    Points
    1 031
    Par défaut
    Salam ;si j'ai bien compris :
    Par exemple sur une ligne le département vaut 2220, il faut que je le remplace en 02220
    j'ai eu le même problème , alors j'ai procéder directement dans phpadmin comme suite :
    champs aaaa : type int , taille/ valeurs 3 , Attributs UNSIGNED ZEROFILL.
    par requête c'est simple en utilisant la syntaxe du raquetteur de mysql

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Voilà la conséquence d'une erreur classique de typage de données !
    Un code postal, c'est un code, pas une quantité ni un nombre, on ne fait jamais de calcul dessus. Il faut donc utiliser le type CHAR(5) pour les codes postaux français.

    Idem pour tout code, référence, numéro qui n'ont aucune vocation à faire l'objet d'un calcul.

    Choisir le bon type de colonne, ça prend 2 secondes. Combien de temps pour chercher la cause du problème rencontré et le résoudre ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par CinePhil
    Un code postal, c'est un code, pas une quantité ni un nombre, on ne fait jamais de calcul dessus. Il faut donc utiliser le type CHAR(5) pour les codes postaux français.
    De mon coté je le perçois plutôt ainsi.

    Cependant, la suggestion de Redoran m'a parue intéressante, et du coup j'ai essayé (vite fait), et ça m'a l'air de fonctionner.

    En quoi troquer un CHAR(5) par un INT(5) UNSIGNED ZEROFILL pourrait mettre à mal MySQL ou Php ?

    Il me semble que coté MySQL (j'en sais rien pour les autres SGBD) toutes les données récupérées en Php sont considérées comme des chaines, du coup un typage (ou cast) en un integer ne devrait pas se faire.
    Du moins il me semble.

    En somme, pour une donnée dans la Bdd comme 02220 quelque soit son type ne devrait pas aboutir par 2220 en Php, non ?


    @ascito
    En tout cas, si tu effectue ce changement de type comme l'a suggéré Redoran, ceci va automatiquement mettre des nombres en 5 caractères, et compléter par des 0 (à gauche) s'il manque des caractères.

    Pourquoi pas après le re-modifier par un CHAR(5), ceci ne devrait rien modifier sur les données.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  8. #8
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    juste pour info:

    la corse... 2a/2b et les dom sont sur 3 chiffres...

    en plus il y a la solution de redoran si tu code sur des chiffres mais aussi des fonctions php ou mysql qui servent à combler à droite ou à gauche par des caractères (ou un groupe de caractères) choisi(s) pour obtenir une chaine de x caractères

    pour bien typer un code il faut bien comprendre ce que l'on manipule comme le dit cinephil...

    après on peut faire des chois de typage et de répartition sur plusieurs colonnes d'un code pour des question de performance de stockage et/ou de recherche dans la table... mais dans le doute mieux vaut se rabattre sur la proposition de cinephil... bien qu'il vaille mieux utiliser varchar à la place de char pour une question de place de stockage...

    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  9. #9
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    On parle ici du code postal français qui est toujours sur 5 chiffres, même pour la Corse (20xxx) et les DOM (3 chiffres de département et 2 pour la partie code postal).

    C'est pour ça que je préconisais un CHAR(5) qui prend moins de place qu'un VARCHAR(5) et qui a tout son sens dans ce cas précis.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

  10. #10
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par ericd69
    pour bien typer un code il faut bien comprendre ce que l'on manipule comme le dit cinephil...
    Tout à fait

    Donc ne par confondre département et code postal.
    Puis comme les codes postaux sont obligatoirement sur 5 chiffres, définir un type de donnée variable comme VARCHAR ne serait pas adapté.

    Citation Envoyé par CinePhil
    je préconisais un CHAR(5) qui prend moins de place qu'un VARCHAR(5) et qui a tout son sens dans ce cas précis
    Oui, entre un CHAR et un VARCHAR.

    Mais vu que les codes postaux sont des chiffres, utiliser un type numérique ne me parais pas dénué de bon sens, non ?
    De plus, un MEDIUMINT(3) prendrait moins de place par rapport à un CHAR()
    La doc :
    MEDIUMINT | 3 octets | -8388608 | 8388607

    Donc théoriquement un MEDIUMINT(3) suffirait et ça occuperait que 3 octets.
    Pour un CHAR(5) ça occuperait 5 octets.
    Soit 2 octets de moins, ça fait pas mal.

    Théoriquement
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ascito Voir le message
    Par exemple sur une ligne le département vaut 2220, il faut que je le remplace en 02220
    Bonjour,
    (à mon avis)
    1/ passer le champ en VARCHAR(5) ou CHAR(5)
    2/ en PHP : faire un UPDATE de toutes les lignes en formatant avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf('%05d', $val['code_postal']);

  12. #12
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    mea culpa pour la confusion cinephil...

    en fait, pour les char ou varchar c'est plus compliqué...
    mysql préconise, si on veut prendre moins de place et qu'on utilise pas toute la largeur de colonne bien sur, de plutôt prendre varchar que char car mysql stocke alors la taille exacte alors qu'en char il stocke la taille max de la colonne...

    pour la place d'un caractère ça dépend du charset choisi...
    utf8, 3 octets (normalement 6 mais mysql a choisi de ne pas implémenté tous les plan de caractères)
    ucs16, 2 octets
    ucs32, 4 octets
    ...

    pour les entiers c'est pas la peine de préciser la valeur entre parenthèse, c'est pas la taille en octet mais le nombre de chiffre significatifs...

    après ça dépend ce que tu veux en faire... il est vrai qu'une jointure sur un entier sera toujours plus efficace que sur des char ou varchar, sans parler des différences entre index sur des entiers ou ces types...

    d'où le fait de pas toujours coller à la sémantique mais de bien réfléchir à ce que tu veux en faire et au éventuelles optimisations...

    le code affiché et le code stocké peuvent avoir des formats différents...

    dans ton cas, pour le code postal, qui n'est constitué que de chiffres, je le stockerais aussi en type entier...

    pour l'affichage soit en php soit en mysql j'utiliserais l'une des fonctions qui comble une chaine par une expression (ici un simple '0') à gauche ou le comblage auto que donnait redoran...

    à toi de voir
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    Merci bien pour vos réponses, du coup j'ai deux belle méthodes pour le faire en mysql et en php ( bien pratique, comme nous sommes surement nombreux à avoir la même base de donnée des département avec des 4 chiffres)

    voilà

    résolu
    Conception / Dev

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/02/2008, 09h17
  2. Effectuer une requête sur une table.
    Par Premium dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 25/05/2007, 17h27
  3. Recupérer le résultat d'une requête sur une table Firebird
    Par defluc dans le forum Bases de données
    Réponses: 7
    Dernier message: 20/04/2007, 19h30
  4. Réponses: 5
    Dernier message: 08/01/2007, 22h03
  5. requéte sur une table
    Par iutcien dans le forum Langage SQL
    Réponses: 1
    Dernier message: 23/06/2006, 16h42

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