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: Création d'une clause WHERE variable pour une requête préparée


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut PDO: Création d'une clause WHERE variable pour une requête préparée
    Bonjour à tous et joyeuses fêtes.
    Dans une application de généalogie, je cherche à faire une sélection de parents possibles.
    J'ai une fonction MySQL avec le code suivant. Dans cette fonction la clause WHERE parait correcte mais je n'arrive pas à écrire le tableau des paramètres pour la fonction execute() (cf. ligne 32):
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    function searchParents(int $idAbo, array $clauses=[]): array|false {
    	$db = dbConnect();
    	var_dump($clauses);
     
    	$where	= [];
    	$where[]= "id_abo=:idAbo";
    	$params	= [':idAbo'=>$idAbo, ];
     
    	foreach($clauses as $key=>$clause) {
     
    		if( in_array($key, ['gender', 'lastname', 'firstname', ]) ){
    			$where[]		= "{$key}=:{$key}";
    			$params[":$key"]= "{$key}";
    		}
     
    	}
     
    	if( !empty('birthY1') && !empty('birthY2') ){
    		$where[] = "( birthyear BETWEEN :birthY1 AND :birthY2 ) OR birthyear IS NULL";
    		$params[":birthY1"] = "birthY1";
    		$params[":birthY2"] = "birthY2";
    	}
     
    	if( !empty('deathY1') && !empty('deathY2') ){
    		$where[] = "( deathyear BETWEEN :deathY1 AND :deathY2 ) OR deathyear IS NULL";
    		$params[":deathY1"] = "deathY1";
    		$params[":deathY2"] = "deathY2";
    	}
     
    	$where = implode("\nAND ", $where);
    	var_dump($where);
    	var_dump($params);
     
     
    	$sql = <<<SQL
    	SELECT
    		id, CONCAT( COALESCE(UPPER(lastname), ''), ' ', COALESCE(firstname, ''), ' ', COALESCE(middlename, '') ) AS fullname,
    		CONCAT( COALESCE(birthday, '--'), '/', COALESCE(birthmonth, '--'), '/', COALESCE(birthyear, '----') ) AS birthdate,
    		' - ', CONCAT( COALESCE(deathday, '--'), '/', COALESCE(deathmonth, '--'), '/', COALESCE(deathyear, '----') ) AS deathdate
    		FROM dat_persons
    		WHERE {$where}
    		ORDER BY lastname, firstname, birthyear, birthmonth, birthday
    	SQL;
    	$stmt = $db->prepare($sql);
    	$stmt->execute($params);
    	var_dump($stmt->fetchAll() );
    	return $stmt->fetchAll();
    }
    Je pense que c'est le tableau d'entrée qui n'est pas bon (mal construit avec valeurs au lieu de variables).
    Je vous donne les valeurs retournées par les var_dump():
    C:\wamp64\www\proginet\appGenealium\model\model.php:3:
    array (size=4)
      'gender' => string 'M' (length=1)
      'lastname' => string 'Paris' (length=5)
      'birthY1' => string '1831' (length=4)
      'birthY2' => string '1907' (length=4)
    
    C:\wamp64\www\proginet\appGenealium\model\model.php:31:string 'id_abo=:idAbo
    AND gender=:gender
    AND lastname=:lastname
    AND ( birthyear BETWEEN :birthY1 AND :birthY2 ) OR birthyear IS NULL
    AND ( deathyear BETWEEN :deathY1 AND :deathY2 ) OR deathyear IS NULL' (length=193)
    
    C:\wamp64\www\proginet\appGenealium\model\model.php:32:
    array (size=7)
      ':idAbo' => int 2
      ':gender' => string 'gender' (length=6)
      ':lastname' => string 'lastname' (length=8)
      ':birthY1' => string 'birthY1' (length=7)
      ':birthY2' => string 'birthY2' (length=7)
      ':deathY1' => string 'deathY1' (length=7)
      ':deathY2' => string 'deathY2' (length=7)
    

  2. #2
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 982
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 982
    Par défaut
    Je n'ai pas tout regardé, mais tester si la chaîne de caractères 'birthY1' est vide ou pas, c'est un peu curieux, non?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if( !empty('birthY1') && !empty('birthY2') ){
    // ...
    if( !empty('deathY1') && !empty('deathY2') ){
    // ...
    J'ai l'impression que tu as écrit 'birthY1' à la place de $clauses['birthY1'].


    Attention aux priorités avec AND et OR: celle de AND est supérieure à celle de OR.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    id_abo=:idAbo
    AND gender=:gender
    AND lastname=:lastname
    AND ( birthyear BETWEEN :birthY1 AND :birthY2 ) OR birthyear IS NULL
    AND ( deathyear BETWEEN :deathY1 AND :deathY2 ) OR deathyear IS NULL

    sera interprété comme:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (
        id_abo=:idAbo
        AND gender=:gender
        AND lastname=:lastname
        AND ( birthyear BETWEEN :birthY1 AND :birthY2 )
    )
    OR
    (
        birthyear IS NULL
        AND ( deathyear BETWEEN :deathY1 AND :deathY2 )
    )
    OR deathyear IS NULL

    Alors qu'il te faudrait plutôt:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    id_abo=:idAbo
    AND gender=:gender
    AND lastname=:lastname
    AND ( birthyear BETWEEN :birthY1 AND :birthY2 OR birthyear IS NULL )
    AND ( deathyear BETWEEN :deathY1 AND :deathY2 OR deathyear IS NULL )

  3. #3
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    J'ai l'impression que tu as écrit 'birthY1' à la place de $clauses['birthY1'].
    Je voyais bien que j'avais une constante au lieu d'une variable mais je ne voyais pas où: Premier bon point.

    Citation Envoyé par CosmoKnacki Voir le message
    Attention aux priorités avec AND et OR. Celle de AND est supérieure à celle de OR.
    Je le savais mais j'avais mal disposé mes parenthèses: Deuxième bon point.

    Mon problème est résolu et tout fonctionne. Un grand Merci!

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 23/10/2009, 00h18
  2. [MySQL] Introduire une variable dans la clause where
    Par ledisciple dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 13/08/2009, 12h39
  3. clause where variable(java)
    Par himou10 dans le forum JDBC
    Réponses: 1
    Dernier message: 06/07/2008, 22h50
  4. Variable d'une clause where avec quote
    Par kcizth dans le forum Langage SQL
    Réponses: 1
    Dernier message: 17/04/2008, 15h43
  5. Réponses: 3
    Dernier message: 11/12/2005, 11h15

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