196 votes

Doctrine - Comment imprimer le vrai sql, pas seulement l'instruction préparée ?

Nous utilisons Doctrine, un ORM PHP. Je crée une requête comme celle-ci :

$q = Doctrine_Query::create()->select('id')->from('MyTable');

et ensuite, dans la fonction, j'ajoute diverses clauses where et d'autres choses selon les besoins, comme ceci

$q->where('normalisedname = ? OR name = ?', array($string, $originalString));

Plus tard, avant execute() -En utilisant cet objet de requête, je veux imprimer le SQL brut afin de l'examiner, et faire ceci :

$q->getSQLQuery();

Cependant, cela n'imprime que l'instruction préparée, et non la requête complète. Je veux voir ce qu'il envoie à MySQL, mais au lieu de cela, il imprime une déclaration préparée, y compris les éléments suivants ? 's. Existe-t-il un moyen de voir la requête "complète" ?

0 votes

Le meilleur moyen que j'ai trouvé pour voir la requête complète est décrit dans cette réponse : stackoverflow.com/a/678310/229077

0 votes

Vous pouvez profiter du travail effectué par Doctrine (le profileur affiche une requête exécutable). Voir ma réponse ci-dessous pour plus de détails

184voto

Pascal MARTIN Points 195780

Doctrine n'envoie pas une "vraie requête SQL" au serveur de base de données : il utilise en fait des instructions préparées, ce qui signifie :

  • Envoi de la déclaration, pour qu'elle soit préparée (c'est ce que renvoie la fonction $query->getSql() )
  • Et, ensuite, l'envoi des paramètres (retournés par $query->getParameters() )
  • et l'exécution des déclarations préparées

Cela signifie qu'il n'y a jamais de "vraie" requête SQL du côté de PHP - donc, Doctrine ne peut pas l'afficher.

21 votes

Pascal : vous ne devriez pas dire que ce n'est pas une "vraie requête SQL" car les instructions préparées sont de vraies requêtes SQL, c'est juste que les paramètres sont envoyés séparément. Cette formulation pourrait prêter à confusion (par ex. olivierpons.fr/2014/03/22/symfony-2-avantages-et-inconvénients ).

3 votes

$query->getParameters(); ne renverra PAS les paramètres dans l'ordre correct, comme ils devraient apparaître dans la requête préparée.

8 votes

Je pense qu'ici l'auteur de la question ne s'est pas soucié de ce que la doctrine envoie ou non. Ce que l'utilisateur et moi voulions savoir, c'est comment obtenir une requête que nous pouvons copier-coller et exécuter sans avoir à remplacer manuellement les points d'interrogation par des paramètres. Comme dans Codeigniter. Je pense que j'avais trouvé cela dans le débogueur de symfony, mais je ne peux toujours pas trouver quand je lance script à partir de la ligne de commande.

132voto

Andy.Diaz Points 563

Un exemple concret :

$qb = $this->createQueryBuilder('a');
$query=$qb->getQuery();
// SHOW SQL: 
echo $query->getSQL(); 
// Show Parameters: 
echo $query->getParameters();

9 votes

Bien que cela fonctionne comme des affectations de variables, vous pourriez envisager ceci : print $query->getSQL() ; foreach ($query->getParameters() as $param) { print "{$param->getName()} -> {$param->getValue()} \n " ; } car vous obtiendrez un résultat plus lisible.

0 votes

Il donne peu d'avantages. Lorsque je copie le sql, je dois toujours rechercher les paramètres où insérer manuellement, ce qui prend beaucoup de temps. Nous voulons une requête avec des paramètres insérés, pourquoi ne pouvons-nous pas le trouver si longtemps ? Même dans le framework Codeigniter, pour autant que je m'en souvienne, dans le profileur, vous pouvez copier la requête et l'exécuter instantanément sans avoir à la chercher manuellement. Nous avons besoin de la même chose pour Symfony.

41voto

alex toader Points 191

Vous pouvez vérifier les requêtes exécutées par votre application si vous enregistrez toutes les requêtes dans mysql :

http://dev.mysql.com/doc/refman/5.1/en/query-log.html

il y aura d'autres requêtes, pas seulement celle que vous recherchez, mais vous pouvez la rechercher par grep.

mais généralement ->getSql(); travaux

Edit :

pour voir toutes les requêtes mysql que j'utilise

sudo vim /etc/mysql/my.cnf 

et ajoutez ces 2 lignes :

general_log = on
general_log_file = /tmp/mysql.log

et redémarrez mysql

14voto

ladenedge Points 4986

getSqlQuery() affiche techniquement la totalité de la commande SQL, mais c'est beaucoup plus utile lorsque vous pouvez également voir les paramètres.

echo $q->getSqlQuery();
foreach ($q->getFlattenedParams() as $index => $param)
  echo "$index => $param";

Pour rendre ce modèle plus réutilisable, il existe une approche intéressante décrite dans le document commentaires à l'adresse SQL brut à partir de Doctrine Query Object .

1 votes

Je sais que c'est un vieux message, mais vos deux liens mènent à une page 404. Pouvez-vous mettre à jour votre réponse s'il vous plaît ? Je demande, parce que je ne suis pas sûr de ce que vous voulez dire par $q . Il ne semble pas que ce soit la requête ou le constructeur de requêtes.

1 votes

J'ai peur de ne pas pouvoir trouver le code le plus réutilisable. $q dans ce cas, est une requête de Doctrine 1. Vous utilisez peut-être Doctrine 2, auquel cas vous voudrez quelque chose comme $qb = $this->createQueryBuilder('a'); $q = $qb->getQuery(); $sql = $q->getSQL(); $params = $q->getParameters(); J'espère que cela vous aidera !

13voto

Ben James Points 41165

Il n'y a pas d'autre requête réelle, c'est ainsi que fonctionnent les déclarations préparées. Les valeurs sont liées dans le serveur de base de données, et non dans la couche applicative.

Voir ma réponse à cette question : En PHP avec PDO, comment vérifier la requête paramétrée SQL finale ?

(Répété ici pour des raisons de commodité :)

L'utilisation d'instructions préparées avec des valeurs paramétrées n'est pas simplement un autre moyen de créer dynamiquement une chaîne de caractères SQL. Vous créez une instruction préparée au niveau de la base de données, puis vous envoyez les valeurs des paramètres seuls.

Donc ce qui est probablement envoyé à la base de données sera un PREPARE ... alors SET ... et enfin EXECUTE ....

Vous ne serez pas en mesure d'obtenir une chaîne SQL comme SELECT * FROM ... même si elle produisait des résultats équivalents, car aucune requête de ce type n'a jamais été envoyée à la base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X