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 :

PDO et instruction SQL CONSTRAINT (MySql) [PDO]


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Par défaut PDO et instruction SQL CONSTRAINT (MySql)
    Bonjour, je suis confronté à un problème insoluble malgré toutes mes recherches concernant l'extension PDO pour php que j'utilise pour la manipulation des tables de ma base MySql...

    Dans une page php, je crée un objet PDO avec tous les paramêtres corrects, la connexion est ouverte avec tous les droits (pour essais).

    Je voudrai créer 2 tables (plus en fait, mais j'ai réduit à 2 pour isoler la source du problème):

    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
    DROP TABLE IF EXISTS `table_01`;
    CREATE TABLE `table_01` (
      `t1_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
      `t1_champ1` VARCHAR(32)  NOT NULL,
      PRIMARY KEY (`t1_id`)
    )
    ENGINE = InnoDB
    CHARACTER SET latin1 COLLATE latin1_swedish_ci;
     
    et
     
    DROP TABLE IF EXISTS `table_02`;
    CREATE TABLE `table_02` (
      `t2_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
      `t2_champ1` VARCHAR(32) NOT NULL,
      `t1_id` INT(11) UNSIGNED NOT NULL,
      PRIMARY KEY (`t2_id`)
    )
    ENGINE = InnoDB
    CHARACTER SET latin1 COLLATE latin1_swedish_ci;
    Jusque là tout va bien, ça passe dans une seule requête de type exec($query);
    Les deux tables sont crées, ça roule...

    Mais si j'ajoute une contrainte pour créer une clé étrangère de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE table_02 ADD CONSTRAINT `FKtable_01` FOREIGN KEY `FKtable_01` ( `t1_id` )  REFERENCES `table_01` ( `t1_id` );
    ça bloque, impossible de créer la clé étrangère, après vérification (essai d'exportation de la base) aucune clé étrangère!

    J'ai essayé deux requêtes séparées, deux objects PDO distincts, un temps d'attente dans le script entre les 2 requêtes et impossible d'ajouter cette clé étrangère.

    De même en essayant directement de mettre la clé étrangère dans la table_02, ça ne marche pas ... C'est d'ailleurs ce que je voulais faire à la base car je préfère établire toutes les clé à la création de la table.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    DROP TABLE IF EXISTS `table_02`;
    CREATE TABLE `table_02` (
      `t2_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
      `t2_champ1` VARCHAR(32) NOT NULL,
      `t1_id` INT(11) UNSIGNED NOT NULL,
      PRIMARY KEY (`t2_id`),
      CONSTRAINT `FKtable_01` FOREIGN KEY `FKtable_01` (`t1_id`)
        REFERENCES `table_01` (`t1_id`)
    )
    ENGINE = InnoDB
    CHARACTER SET latin1 COLLATE latin1_swedish_ci;

    Dernière chose: si les 2 tables existent, et si je rappelle le script avec la requête ALTER TABLE seulement, ça fonctionnes: mes clé étrangères sont bien créées...
    Naturellement, si je fait ces requêtes d'un coup dans phpMyAdmin, ça tourne aussi.

    En gros, il faut que j'appelle 2 scripts pour que ça marche, ce qui ne m'arrange pas du tout, car j'aimerai tout faire en une seule fois, pour le confort de l'utilisateur notamment.

    Drole de binz, si quelqu'un a une idée...

    Merci d'avance

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Pourrais-tu nous montrer ton script ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Par défaut
    Je pense que ça devrait suffire niveau code...
    Il me semble que c'est plutôt standard.

    Je récupère les instructions du fichier SQL dans une variable, puis j'exécute une requête via l'objet PDO.

    La connexion fonctionne bien, puisque j'arrive à créer des tables simples sans clés étrangères.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $sql_filename = SN_ROOTDIR.'/sql/sn_creator.sql';
    $sql_file = fopen($sql_filename,'r');
    $sn_create = fread($sql_file,filesize($sql_filename));
    fclose($sql_file);
     
     
    try
    {
    $pdo_cnx = new PDO("mysql:host=$dbhostdbname=$dbname",$dbuser,$dbpwd);
     
    $pdo_cnx->exec($sn_create);
    }
    catch
    {...}
    fichier *.sql:

    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
    DROP TABLE IF EXISTS `table_01`;
    CREATE TABLE `table_01` (
      `t1_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
      `t1_champ1` VARCHAR(32)  NOT NULL,
      PRIMARY KEY (`t1_id`)
    )
    ENGINE = InnoDB
    CHARACTER SET latin1 COLLATE latin1_swedish_ci;
     
    DROP TABLE IF EXISTS `table_02`;
    CREATE TABLE `table_02` (
      `t2_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
      `t2_champ1` VARCHAR(32) NOT NULL,
      `t1_id` INT(11) UNSIGNED NOT NULL,
      PRIMARY KEY (`t2_id`)
    )
    ENGINE = InnoDB
    CHARACTER SET latin1 COLLATE latin1_swedish_ci;
     
    ALTER TABLE table_02 ADD CONSTRAINT `FKtable_01` FOREIGN KEY `FKtable_01` ( `t1_id` )  REFERENCES `table_01` ( `t1_id` )
    Ce qui coince, c'est la contrainte de clé étrangère, qu'elle soit sous forme d'ALTER TABLE ou directement incluse dans la création de la table... ...
    La seule solution que j'ai trouvé, c'est de faire appel à un autre script (donc une autre page ou recharger la page avec une sections spécifique).
    Mais je ferai ça vraiment en dernier recourt, c'est pas pratique, ni pour moi ni pour l'utilisateur, et ça dépasse totalement la logique et les capacités de PDO !

    Bon ok c'est pas les smileys qui vont régler mon blème ...

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    quand tu mets "*.sql", tu veux dire que chaque instruction est dans un fichier different ?

    Ayant testé dans un seul fichier, et bien que exec() ne soit pas censé executer plusieurs requetes, je vais quand meme jusqu'a la création de la premiere table.

    En executant les 3 requetes separement, cela fonctionne pour moi.

    Au passage, il y a un probleme d'ordre : on ne peut pas DROP la table1 avant la table2 si elle existe a cause de la contrainte.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Pour moi il y a une erreur de syntaxe, le 2e `FKtable_01` est de trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE table_02 ADD CONSTRAINT `FKtable_01` FOREIGN KEY `FKtable_01` ( `t1_id` )  REFERENCES `table_01` ( `t1_id` )
    Le code correct serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE table_02 ADD CONSTRAINT `FKtable_01` FOREIGN KEY ( `t1_id` )  REFERENCES `table_01` ( `t1_id` )

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Par défaut
    Alors, non c'est un fichier nommé sn_creator.sql qui contient toutes les instructions, les 2 tables et l'alter table...

    Je ne savais pas que exec() n'était pas censé exécuter plusieurs requêtes.
    A prioris il arrive quand même à créer 2 tables sans contraintes.
    Au fait, par requête vous entendez une instruction terminée par un ';'?

    Sabotage, merci pour le tuyau DROP TABLE, effectivement c'est une (grosse) erreur de ma part, PHPMyAdmin aurait ralé si j'avais fait ça!

    Je vais essayer séparément et dans le bon ordre!

    Rbaraer, tu as surement raison, je viens de relire la doc, et on ne spécifie pas d'identifiant pour une clé étrangère (l'identifiant étant le ou les champs concernés).
    J'ai tellement lu et relu les docs et les divers sujets que je suis aussi passé à côté de ça.

    Et bien, je vais essayer tout ça et je vous tiens au courant, ça pourra toujours servir à d'autres!

    Merci à vous !

    Nico

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par freeman_357 Voir le message
    Rbaraer, tu as surement raison, je viens de relire la doc, et on ne spécifie pas d'identifiant pour une clé étrangère (l'identifiant étant le ou les champs concernés).
    En fait si, l'identifiant de la CE est là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE table_02 ADD CONSTRAINT `FKtable_01` 
    FOREIGN KEY ( `t1_id` )  REFERENCES `table_01` ( `t1_id` );
    Mais on ne le répète pas après "FOREIGN KEY"

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Par défaut
    OK merci pour l'info !

    Donc j'ai finalement bien séparé les requêtes, avec un truc du genre une requête par case d'un tableau de requêtes, puis un foreach cases:
    je prépare puis exécute... Pas d'arguments vu que c'est la création du squelette de ma base!

    Donc à retenir: le couple prepare & execute ainsi que exec ou query ne peuvent exécuter qu'une seule requête semblerait-il.

    En espérant que ça puisse servir à d'autres à pas trop galérer comme moi !

    Merci à vous pour l'aide.

    Nico

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

Discussions similaires

  1. Instruction SQL dans un bouton pour filtrer info formulaire
    Par beegees dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 05/09/2005, 13h26
  2. Réponses: 3
    Dernier message: 06/10/2004, 15h38
  3. Instruction SQL et Date
    Par Didier100 dans le forum Bases de données
    Réponses: 11
    Dernier message: 19/07/2004, 18h20
  4. Instruction SQL qui supprime une colonne d'une table
    Par tseg dans le forum Langage SQL
    Réponses: 2
    Dernier message: 31/10/2003, 20h47
  5. Passer de la zone d'édition vers une instruction sql
    Par tripper.dim dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/11/2002, 14h44

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