Sujet : [Résolu] Hoa_Database_Dal et requêtes préparées.

Hey big_smile !

À cette heure tardive, je suis en plein développement de ce qui sera bientôt (je l'espère) une version fonctionnelle de mon site web. Et plus particulièrement sur la base données.
Je vais passer les détails, et résumer le problème au plus simple. J'ai ce code :

$db = Hoa_Database_Dal::getInstance( 'default' );

$statement = $db->prepare( '
    SELECT *
    FROM maTable
    LIMIT :count
;' );

var_dump( $statement->execute( array( ':count' => 5 ) )
                    ->fetchAll() );

À priori, il est censé me renvoyer les cinq premiers enregistrements de maTable. Mais à la place, j'ai une belle Hoa_Database_Dal_Exception qui me dit :

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''5'' at line 3

Bref, pas tout à fait ce que je cherche. Alors dans un éclaire de lucidité, je remplace les dernières lignes de mon code par :

$count = 5;
$statement->bindParameter( ':count', $count );
var_dump( $statement->execute( /* plus rien ici */ )
                    ->fetchAll() );

Cette fois-ci, plus d'exception, alors que la requête finale devrait être identique, sauf erreur de ma part (me l'indiquer dans ce cas tongue).
MAIS ! ladite requête ne me renvoie aucun résultat, et je peux assurer qu'il y en a. Histoire de vérifier que mes connaissances rouillées du SQL n'étaient pas en cause, j'ai tenté cet autre code :

$statement = $db->query( '
    SELECT *
    FROM maTable
    LIMIT 5
;' );
var_dump( $statement->fetchAll() );

Et là, TA-DAA ! ça fonctionne big_smile ! Mais je ne peux pas profiter de ma requête préparée sad.

Alors je cherche à comprendre pourquoi mon premier code renvoie une erreur de syntaxe, et le second aucun résultat, alors que les deux sont je crois équivalents au dernier (au niveau de la requête finale censée être envoyée)...
Quelqu'un pour m'éclairer de ses lumières big_smile ?

PS : au passage, une question qui n'a rien à voir avec ça : il y a un print_r() caché à la ligne 401 de Hoa_Locale. Paquetage encore en développement ou oubli ?

Dernière fois dit par Torajio BANGANI (05 Aug. 2010 17:29)

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Nouvelles données : le second code (avec bindParameter()) ne renvoie aucune donnée, car la requête n'a pas l'air d'être vraiment exécutée. En effet, un fetchAll() renvoie un tableau vide, et ce même si je remplace ma requête préparée par n'importe quoi :

$statement = $db->prepare( 'The quick brown fox jumps over the lazy dog.' );

$count = 5;
$statement->bindParameter( ':count', $count );
var_dump( $statement->execute()
                    ->fetchAll() );

/* Résultat : array(0) { } */

J'ai donc essayé de voir ce qui n'allait pas avec la méthode bindParameter() en fouillant dans le code, mais honnêtement, je n'arrive pas à m'y retrouver dans les appels. Donc cette méthode, dont le troisième argument semble préciser le type de la variable, ne fonctionne pas, je ne sais pas pourquoi, alors qu'elle pourrait bien m'aider tongue .

Le premier code fonctionne quant à lui big_smile ! Oui, mais il intègre la valeur dans la requête en tant que chaîne, non pas en tant qu'entier. Je me retrouve donc avec ce type de requête :

SELECT *
FROM maTable
LIMIT '5';

D'où l'erreur de syntaxe. Et c'est pour ça que bindParameter(), qui me permettrait de préciser le type, me serait d'une grande aide... si elle fonctionnait wink !

Voilà pour mes petites recherches personnelles. Je vais continuer un peu l'investigation, je finirai bien par trouver. Je ne tiens pas à avoir la même requête écrite à trois reprises dans le même fichier, juste parce que deux valeurs changent chaque fois yikes !

EDIT : Moar tests big_smile !
J'ai finalement réussi à reconstruire le chemin entre les méthodes du Hoa_Database_DalStatement et celle du PDOStatement qu'il y a au bout. Alors j'ai pu vérifier que tout fonctionnait, toutes les méthodes sont appelées normalement, mais le résultat final reste désespérément vide...

J'ai passé quelques heures de ma journée pour trouver une solution à ce problème, mais pour le moment, je n'ai pas avancé d'un poil depuis ce matin. Alors je ne vais pas faire un blocage là-dessus, je passe à autre chose, en mettant une solution temporaire assez lourde, mais qui me permettra de continuer le reste du développement.

Et si quelqu'un a une subite illumination, qu'il se fasse connaître big_smile !

Dernière fois dit par Torajio BANGANI (03 Aug. 2010 17:48)

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Bonjour,

Désolé de ne pouvoir t'aider ! Je me suis pas penché sur les requêtes préparées. J'en vois pas une grande utilité.
Je m'y retrouve très bien dans mes requêtes

" L'imagination est plus importante que la connaissance. La connaissance est limitée alors que l'imagination englobe le monde entier, stimule le progrès, suscite l'évolution. " - Life in the cloud :: Getting Started with Hoa - Hoa débutant

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Elles sont utiles dans des cas particuliers, comme quand on doit travailler souvent avec plusieurs tables dont tous les champs sont identiques. Je crois qu'elles permettent aussi de mieux contrôler la sécurité : on peut préciser le type des variables liées, ce qui évite d'oublier de sécuriser les données envoyées par l'utilisateur.

Mais bon, dans mon cas précis, la requête préparée me permettait de ne pas dupliquer le code d'une requête de quelques lignes seulement, ainsi que d'éviter deux rappels de l'instance Hoa_Database_Dal. Plus une question d'esthétique du code qu'une réelle nécessité pratique smile .
Toujours est-il que je suis curieux de savoir pourquoi ça ne fonctionne pas...

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Je vais tester tout à l'heure après ma pause café + pain aux raisins

" L'imagination est plus importante que la connaissance. La connaissance est limitée alors que l'imagination englobe le monde entier, stimule le progrès, suscite l'évolution. " - Life in the cloud :: Getting Started with Hoa - Hoa débutant

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Moi ça marche très bien !

                
import('Database.Dal.~');
                
$this->db = Hoa_Database_Dal::getInstance('myConn');
                
$statement = $this->db->prepare('SELECT * FROM page ' .
       'WHERE url > :pageName ');
            
$statement->execute(array(
       ':pageName' => $pageName
));
            
echo print_r($statement->fetchAll());
" L'imagination est plus importante que la connaissance. La connaissance est limitée alors que l'imagination englobe le monde entier, stimule le progrès, suscite l'évolution. " - Life in the cloud :: Getting Started with Hoa - Hoa débutant

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Le problème est qu'en donnant les valeurs dynamiques (:pageName dans ton code) directement dans la méthode execute(), elles sont automatiquement considérées comme des chaînes. Dans une clause WHERE, pas de problème. Dans une clause LIMIT, ça ne fonctionne plus wink .
Cependant, je viens de trouver d'où venait le problème, justement en me questionnant un peu plus sur les types des données et là où elles sont placées.

PDO définit six constantes pour préciser le type de donnée insérée de la forme PDO::PARAM_XXX. Chacune a son utilité : par exemple, PARAM_STR va encapsuler la valeur entre apostrophes, comme toute chaîne en SQL, alors que PARAM_INT n'en mettra pas si c'est effectivement un entier.
Le problème est que quelque soit le type précisé, dès lors que c'est une chaîne, elle est encapsulée. Donc lorsque mon paramètre est le nom d'une table, forcément, SELECT * FROM 'machin', ça passe pas. Et pas moyen de remplacer ces [''] par des [``].

Bref, définitivement, je crois que c'est pas possible de faire des requêtes préparées qui changent de table ^^ .

Donc problème résolu, et merci pour le coup de main wink !

PS : Ah oui, dans mon code avec bindParameter(), le retour est toujours un tableau vide, puisque le PDOStatement qui est au bout de la chaîne renvoyait FALSE : erreur de syntaxe, à cause de l'encapsulation des noms de table.
D'ailleurs, ce serait bien si une exception était lancée à ce moment-là, dans la classe Hoa_Database_Dal_AbstractLayer_Xxx_XxxStatement. Pour ceux qui ont la mauvaise habitude de ne pas vérifier la sortie de toutes les fonctions avant utilisation, ce serait une grande aide au débogage smile .

Dernière fois dit par Torajio BANGANI (05 Aug. 2010 17:34)

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

J'ai très bien compris le problème il faudrait pouvoir vérifier lors de la fonction execute() si la clé n'est pas :tableName et directement il ajouterai pas les ['']

A quoi sert vraiment les [``] en SQL ? (déco tongue, ou plutôt les anciennes normes SQL ??)

" L'imagination est plus importante que la connaissance. La connaissance est limitée alors que l'imagination englobe le monde entier, stimule le progrès, suscite l'évolution. " - Life in the cloud :: Getting Started with Hoa - Hoa débutant

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Les [``] permettent d'échapper les noms des tables ou des champs lorsque ceux-ci interfèrent avec des mots-clés.
Par exemple, si un jour tu as la bonne idée de créer une table "select" qui comporte des champs comme "order", "count", or "if", ces accents les empêche d'être interprétés.
Mais personnellement, je les utilise comme convention d'écriture dans mes requêtes. Donc comme je ne donne jamais de nom ambigu à mes champs, la plupart du temps, ces "apostrophes obliques" ne servent à rien. Enfin si : la différence entre les alias de champs ou de tables et leurs noms réels est plus claire smile .

10

Re : [Résolu] Hoa_Database_Dal et requêtes préparées.

Hey smile,

Cool que ton problème soit résolu. Désolé de ne pas avoir pu intervenir plus tôt smile.

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »