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 ne renvoie pas de résultat alors que la requête dans Mysql en renvoie [PDO]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 44
    Par défaut PDO ne renvoie pas de résultat alors que la requête dans Mysql en renvoie
    Bonjour.

    Dans le cas d'une requête pas très conventionnelle ( https://www.developpez.net/forums/d1...on-n-possible/ ), utilisant UNION et des colonnes fictives, la requête exécutée dans le client mysql fonctionne parfaitement mais pas avec PDO.
    Contenant une clause LIMIT, cela évoque immédiatement l'habituel problème nécessitant l'usage préalable de ATTR_EMULATE_PREPARES.
    Malgré tout, cela ne fonctionne toujours pas (ne renvoie aucun résultat) et le catch ne renvoie aucune erreur.

    Cela ne semble pas être attribué à LIMIT car en supprimant la ligne LIMIT, cela ne renvoie là aussi aucun résultat.

    Auriez-vous une idée afin de résoudre mon problème?

    Merci.

    La requête
    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
     
    	SELECT 
    							'S'	AS TENR,
    							0   AS P1,
    							TS.item_id AS	P2,
    							TS.category_id,
    							TS.item_name AS CONTENU,
    							TS.item_create_time AS HORODATE
    					FROM TABLE2 AS TS
    							WHERE TS.item_name LIKE :a
     
    					UNION
     
    					SELECT 
    							'P'	AS TENR,
    							TP.produit_id AS	P1,
    							TP.categorie_id aS  P2,
    							TP.magasin_id,
    							TP.descriptif AS CONTENU,
    							TP.heure_enregistrement AS HORODATE
    					FROM TABLE1 AS TP
    							WHERE TP.descriptif LIKE :a
     
     
     
    					ORDER BY HORODATE DESC LIMIT 0,30

    Code php


    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
     
     
    <?php
     
     
    $dbh = new PDO('mysql:host=localhost;dbname=test;port=3306','utilisateur','mot_de_passe');
    $dbh->exec("SET CHARACTER SET utf8");
     
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);    
     
    $requete = "
    
    	SELECT 
    							'S'	AS TENR,
    							0   AS P1,
    							TS.item_id AS	P2,
    							TS.category_id,
    							TS.item_name AS CONTENU,
    							TS.item_create_time AS HORODATE
    					FROM TABLE2 AS TS
    							WHERE TS.item_name LIKE :a
    
    					UNION
    
    					SELECT 
    							'P'	AS TENR,
    							TP.produit_id AS	P1,
    							TP.categorie_id aS  P2,
    							TP.magasin_id,
    							TP.descriptif AS CONTENU,
    							TP.heure_enregistrement AS HORODATE
    					FROM TABLE1 AS TP
    							WHERE TP.descriptif LIKE :a
    	
    					ORDER BY HORODATE DESC LIMIT 0,30
    
    
    ";
     
     
    $parametres = array(
    						'a'	=> '%blé%'
    					);
    try
    {   
    	$sql = $dbh->prepare($requete);
     
    	$sql->execute($parametres);
    }
    catch (PDOException $e) 
    {     
    	echo 	$e->getCode().' '. $e->getMessage();
    }
     
     
    $extraction = $sql->fetchAll(PDO::FETCH_ASSOC);
     
    foreach ($extraction as $ligne)
    {
    		print_r($ligne);
     
    }
     
     
    ?>

    Résultat d'exécution de la requête dans client mysql
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    S	0	3	29	Farine de blé	1154322935
    P	8	8	19	Biscuits gerblé	1137085482
    P	6	6	7	Conserves de blé germé	1136969576
    P	2	2	18	Palette de farine de blé	1136966647
    Si j'exécute avec PDO la requête en remplaçant :a par une valeur cela fonctionne.

    En pièce-jointe, fichier sql de test.

    Merci.
    Fichiers attachés Fichiers attachés

  2. #2
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $dbh = new PDO('mysql:host=localhost;dbname=test;port=3306','utilisateur','mot_de_passe');
    $dbh->exec("SET CHARACTER SET utf8");
     
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $dbh = new PDO('mysql:host=localhost;dbname=test;port=3306;charset=UTF8','utilisateur','mot_de_passe',
    				array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION   , PDO::ATTR_EMULATE_PREPARES =>FALSE));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $parametres = array(
    						'a'	=> '%blé%'
    					);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $parametres = array(	':a'	=> '%blé%');
    A+.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 44
    Par défaut
    Bonjour Andry,

    Merci pour ton aide.

    Pour ta suggestion de remplacer dans le tableau de paramètres 'a' par ':a', que j'avais essayé, (le : semble optionnel voir https://php.net/manual/en/pdostateme...cute.php#71929 ) , cela n'a aucun impact.

    Avec l'ajout de PDO::ERRMODE_EXCEPTION (au temps pour moi pour l'oubli), l'erreur suivante m'est renvoyée :
    HY093 SQLSTATE[HY093]: Invalid parameter number

    J'utilise à deux reprises :a dans la requête.

    Si je pose deux "named parameters" différents dans la requête et leur affectant la même valeur, et que dans le tableau de paramètres j'indique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $parametres = array(
    						'a'	=> '%blé%',
    						'b'	=> '%blé%'
    					);
    cela fonctionne.

    Malgré tout, je ne comprends pas pourquoi l'exemple d'avant ne fonctionnait pas. N''est-il pas possible d'utiliser un même "named parameter" à plusieurs reprises dans la requête ?


    Merci.

  4. #4
    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
    Normalement, oui, on peut utiliser deux fois le même paramètre nommé. Mais personnellement, j'ai toujours utilisé le :a dans la requête et dans la définition du paramètre.
    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 !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    1-
    Citation Envoyé par mkdir Voir le message
    ...le : semble optionnel...
    Même s'il est optionnel, il est préférable de le mettre.
    C'est plus lisible (on distingue mieux les noms de colonnes / placeholders nommés / variable PHP *), et donc facile à déboguer.

    * ex. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $SQL = "............ WHERE nom_colonne = :nom_placeholder....";
    ....->execute( array( ':nom_placeholder' => $nom_variable) );
    2-
    ...N'est-il pas possible d'utiliser un même "named parameter" à plusieurs reprises dans la requête ?..
    Voir : PDO::prepare

    Vous devez inclure un marqueur avec un nom unique pour chaque valeur que vous souhaitez passer dans la requête lorsque vous appelez PDOStatement::execute().
    Vous ne pouvez pas utiliser un marqueur avec deux noms identiques dans une requête préparée, à moins que le mode émulation ne soit actif.
    Voir : PDO::ATTR_EMULATE_PREPARES

    Active ou désactive la simulation des requêtes préparées.
    Certains pilotes ne supportent pas nativement les requêtes préparées ou en ont un support limité.
    Ce paramètre force PDO à émuler (TRUE et la simulation des requêtes préparées sont pris en charge par le pilote) les requêtes préparées ou (FALSE) à utiliser l'interface native.
    Il tentera toujours une émulation si le pilote n'a pas de support natif. bool requis.
    Dernière modification par Invité ; 11/07/2018 à 09h38.

  6. #6
    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
    Il me semble pourtant avoir déjà utilisé deux fois le même paramètre nommé sans spécifier le PDO::ATTR_EMULATE_PREPARES !

    Mais en utilisant bindParam par contre.
    $sql->bindParam(':a', '%blé%', PDO::PARAM_STR);
    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 !

  7. #7
    Invité
    Invité(e)
    Par défaut
    Je suis d'accord avec toi, SAUF si on met volontairement ATTR_EMULATE_PREPARES à false !
    (voir le code dans le 1er message !)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?php
    $dbh = new PDO('mysql:host=localhost;dbname=test;port=3306','utilisateur','mot_de_passe');
    $dbh->exec("SET CHARACTER SET utf8");
     
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 44
    Par défaut
    Merci pour ces précisions, je confirme le dernier message de jreaux62, j'ai fait des essais avec et sans ATTR_EMULATE_PREPARES dans une requête simple avec réutilisation d'un même marqueur, j'obtiens bien ce qui est décrit.

  9. #9
    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 perso avec PHP 5.6.36 et MariaDB 10.1.33-MariaDB...
    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
    <?php
    /**
     * Test d'utiliation multiple du même paramètre nommé dans une requête SQL avec PDO.
     *
     * @filesource	chemin/test_PDO.php
     * @author : Philippe Leménager
     * @version : V 0.1 - 11 juil. 2018 - plemenager - Création
     */
     
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
     
    $pdo = new PDO('mysql:host=localhost;dbname=test;port=3306', 'test', 'test', array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
     
    $sql = "
    	SELECT Sort_Order, Commo_Name, Formal_Name, ISO_3166_1_2_Letter_Code
    	FROM tc_pays
    	WHERE Commo_Name = :search
    		OR Formal_Name = :search
    ";
     
    $search = 'France';
     
    $sth = $pdo->prepare($sql);
     
    $sth->bindParam(':search', $search, PDO::PARAM_STR);
     
    $sth->execute();
     
    $result = $sth->fetchAll();
     
    var_dump($result);
    Résultat :
    array(1) { [0]=> array(8) { ["Sort_Order"]=> string(2) "60" [0]=> string(2) "60" ["Commo_Name"]=> string(6) "France" [1]=> string(6) "France" ["Formal_Name"]=> string(15) "French Republic" [2]=> string(15) "French Republic" ["ISO_3166_1_2_Letter_Code"]=> string(2) "FR" [3]=> string(2) "FR" } }
    À moins que la valeur par défaut de PDO::ATTR_EMULATE_PREPARES soit la bonne, je ne l'ai pas spécifiée par moi-même !
    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 !

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

Discussions similaires

  1. Requete qui ne renvoie pas de résultat
    Par bruno782 dans le forum Requêtes
    Réponses: 6
    Dernier message: 01/08/2019, 13h39
  2. [PostgreSQL] Pas de résultat alors que la requête est bonne
    Par CinePhil dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 09/10/2017, 15h30
  3. Réponses: 4
    Dernier message: 15/02/2015, 12h47
  4. MySQL ne renvoie pas d'erreur alors que la chaine est fausse
    Par repié dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 07/11/2007, 12h18
  5. Réponses: 7
    Dernier message: 30/12/2006, 17h13

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