Frage

Wir verwenden Lehre, eine PHP-ORM. Ich bin eine Abfrage wie folgt erstellen:

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

und dann in der Funktion, die ich hinzugefügt habe in verschiedenen where-Klauseln und Dinge gegebenenfalls wie folgt

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

Später, bevor execute()-ing, das Query-Objekts, ich mag den rohen SQL, um zu drucken, um es zu untersuchen, und dies zu tun:

$q->getSQLQuery();

Allerdings, dass nur druckt die vorbereitete Anweisung, nicht die vollständige Abfrage. Ich will sehen, was es mit dem MySQL sendet, sondern es wird eine vorbereitete Erklärung ausdrucken, einschließlich ? ist. Gibt es eine Möglichkeit, die ‚voll‘ Abfrage zu sehen?

War es hilfreich?

Lösung

Lehre ist nicht eine „echte SQL-Abfrage“, um den Datenbankserver gesendet: es ist tatsächlich mit Prepared Statements, das heißt:

  • Senden der Anweisung, darauf vorbereitet zu sein (das ist, was durch $query->getSql() zurückgegeben wird)
  • Und dann sendet die Parameter (zurückgegeben durch $query->getParameters())
  • und Ausführung der vorbereiteten Anweisungen

Das heißt, es ist nie eine „echte“ SQL-Abfrage auf der PHP-Seite -. So kann Lehre nicht angezeigt

Andere Tipps

Ein Arbeitsbeispiel:

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

Sie können die Abfrage durch Ihre Anwendung ausgeführt, wenn Sie alle Abfragen in mysql log:

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

wird es mehr Anfragen nicht nur die, die Sie suchen, aber Sie können es grep.

, aber in der Regel ->getSql(); Werke

Edit:

Alle MySQL-Abfragen sehen Ich verwende

sudo vim /etc/mysql/my.cnf 

und fügen Sie diese 2 Zeilen:

general_log = on
general_log_file = /tmp/mysql.log

und Neustart mysql

Ich habe einen Doctrine2 Logger erstellt, der dies tut genau das. Es „Hydrate“ die parametrisierte SQL-Abfrage mit den Werten Lehre 2 eigenen Datentyp conversors verwendet wird.

<?php


namespace Drsm\Doctrine\DBAL\Logging;
use Doctrine\DBAL\Logging\SQLLogger,
    Doctrine\DBAL\Types\Type,
    Doctrine\DBAL\Platforms\AbstractPlatform;
/**
 * A SQL logger that logs to the standard output and
 * subtitutes params to get a ready to execute SQL sentence

 * @author  dsamblas@gmail.com
 */
class EchoWriteSQLWithoutParamsLogger implements SQLLogger

{
    const QUERY_TYPE_SELECT="SELECT";
    const QUERY_TYPE_UPDATE="UPDATE";
    const QUERY_TYPE_INSERT="INSERT";
    const QUERY_TYPE_DELETE="DELETE";
    const QUERY_TYPE_CREATE="CREATE";
    const QUERY_TYPE_ALTER="ALTER";

    private $dbPlatform;
    private $loggedQueryTypes;
    public function __construct(AbstractPlatform $dbPlatform, array $loggedQueryTypes=array()){
        $this->dbPlatform=$dbPlatform;
        $this->loggedQueryTypes=$loggedQueryTypes;
    }
    /**
     * {@inheritdoc}
     */
    public function startQuery($sql, array $params = null, array $types = null)

    {
        if($this->isLoggable($sql)){
            if(!empty($params)){
                foreach ($params as $key=>$param) {
                    $type=Type::getType($types[$key]);
                    $value=$type->convertToDatabaseValue($param,$this->dbPlatform);
                    $sql = join(var_export($value, true), explode('?', $sql, 2));
                }

            }
            echo $sql . " ;".PHP_EOL;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function stopQuery()
    {

    }
    private function isLoggable($sql){
        if (empty($this->loggedQueryTypes)) return true;
        foreach($this->loggedQueryTypes as $validType){
            if (strpos($sql, $validType) === 0) return true;
        }
        return false;
    }
}

Verwendungsbeispiel :; In der folgenden Friede von Code auf der Standardausgabe wird Echo jeder INSERT, UPDATE, DELETE SQL Sätze generierten mit $ em Entity-Manager

/**@var  \Doctrine\ORM\EntityManager $em */
$em->getConnection()
                ->getConfiguration()
                ->setSQLLogger(
                    new EchoWriteSQLWithoutParamsLogger(
                        $em->getConnection()->getDatabasePlatform(),
                        array(
                            EchoWriteSQLWithoutParamsLogger::QUERY_TYPE_UPDATE,
                            EchoWriteSQLWithoutParamsLogger::QUERY_TYPE_INSERT,
                            EchoWriteSQLWithoutParamsLogger::QUERY_TYPE_DELETE
                        )
                    )
                );

Es gibt keine andere wirkliche Abfrage, das ist, wie vorbereitete Anweisungen arbeiten. Die Werte werden in dem Datenbank-Server gebunden ist, nicht in der Anwendungsschicht.

Sehen Sie meine Antwort auf diese Frage: In PHP mit PDO, wie die endgültigen SQL parametrisierte Abfrage überprüfen?

(Wiederholte hier der Einfachheit halber:)

  

Mit Prepared Statements mit parametrisierte Werte ist nicht einfach eine andere Art und Weise, um dynamisch eine Reihe von SQL zu erstellen. Sie erstellen eine vorbereitete Anweisung in der Datenbank, und dann allein um die Parameterwerte senden.

     

Also, was wahrscheinlich an die Datenbank gesendet einen PREPARE ... wird, dann SET ... und schließlich EXECUTE ....

     

Sie werden nicht in der Lage sein, einige SQL-Zeichenfolge wie SELECT * FROM ... zu bekommen, auch wenn es gleichwertige Ergebnisse produzieren würde, weil eine solche Abfrage jemals tatsächlich an die Datenbank gesendet wurde.

getSqlQuery() besagt technisch den gesamten SQL-Befehl, aber es ist viel mehr nützlich, wenn Sie auch die Parameter sehen können.

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

Um dieses Muster wieder verwendbaren mehr zu machen, dann ist es ein schöner Ansatz in der Kommentare unter Raw SQL aus Lehre Abfrageobjekt .

Meine Lösung:

 /**
 * Get SQL from query
 * 
 * @author Yosef Kaminskyi 
 * @param QueryBilderDql $query
 * @return int
 */
public function getFullSQL($query)
{
    $sql = $query->getSql();
    $paramsList = $this->getListParamsByDql($query->getDql());
    $paramsArr =$this->getParamsArray($query->getParameters());
    $fullSql='';
    for($i=0;$i<strlen($sql);$i++){
        if($sql[$i]=='?'){
            $nameParam=array_shift($paramsList);

            if(is_string ($paramsArr[$nameParam])){
                $fullSql.= '"'.addslashes($paramsArr[$nameParam]).'"';
             }
            elseif(is_array($paramsArr[$nameParam])){
                $sqlArr='';
                foreach ($paramsArr[$nameParam] as $var){
                    if(!empty($sqlArr))
                        $sqlArr.=',';

                    if(is_string($var)){
                        $sqlArr.='"'.addslashes($var).'"';
                    }else
                        $sqlArr.=$var;
                }
                $fullSql.=$sqlArr;
            }elseif(is_object($paramsArr[$nameParam])){
                switch(get_class($paramsArr[$nameParam])){
                    case 'DateTime':
                             $fullSql.= "'".$paramsArr[$nameParam]->format('Y-m-d H:i:s')."'";
                          break;
                    default:
                        $fullSql.= $paramsArr[$nameParam]->getId();
                }

            }
            else                     
                $fullSql.= $paramsArr[$nameParam];

        }  else {
            $fullSql.=$sql[$i];
        }
    }
    return $fullSql;
}

 /**
 * Get query params list
 * 
 * @author Yosef Kaminskyi <yosefk@spotoption.com>
 * @param  Doctrine\ORM\Query\Parameter $paramObj
 * @return int
 */
protected function getParamsArray($paramObj)
{
    $parameters=array();
    foreach ($paramObj as $val){
        /* @var $val Doctrine\ORM\Query\Parameter */
        $parameters[$val->getName()]=$val->getValue();
    }

    return $parameters;
}
 public function getListParamsByDql($dql)
{
    $parsedDql = preg_split("/:/", $dql);
    $length = count($parsedDql);
    $parmeters = array();
    for($i=1;$i<$length;$i++){
        if(ctype_alpha($parsedDql[$i][0])){
            $param = (preg_split("/[' ' )]/", $parsedDql[$i]));
            $parmeters[] = $param[0];
        }
    }

    return $parmeters;}

Beispiel für die Verwendung:

$query = $this->_entityRepository->createQueryBuilder('item');
$query->leftJoin('item.receptionUser','users');
$query->where('item.customerid = :customer')->setParameter('customer',$customer)
->andWhere('item.paymentmethod = :paymethod')->setParameter('paymethod',"Bonus");
echo $this->getFullSQL($query->getQuery());

Sie können einfach die SQL-Parameter auf den folgenden Ansatz.

   $result = $qb->getQuery()->getSQL();

   $param_values = '';  
   $col_names = '';   

   foreach ($result->getParameters() as $index => $param){              
            $param_values .= $param->getValue().',';
            $col_names .= $param->getName().',';
   } 

   //echo rtrim($param_values,',');
   //echo rtrim($col_names,',');    

Wenn Sie also die $param_values und $col_names ausgedruckt, können Sie die Parameterwerte, die durch die SQL und entsprechende Spaltennamen erhalten.

. Hinweis: Wenn $param ein Array zurückgibt, müssen Sie Iterierte erneut als Parameter innerhalb IN (:?) kommt in der Regel als verschachtelte Array

Inzwischen, wenn Sie einen anderen Ansatz gefunden, mit uns bitte so freundlich sein Anteil:)

Danke!

Weitere klare Lösung:

 /**
 * Get string query 
 * 
 * @param Doctrine_Query $query
 * @return string
 */
public function getDqlWithParams(Doctrine_Query $query){
    $vals = $query->getFlattenedParams();
    $sql = $query->getDql();
    $sql = str_replace('?', '%s', $sql);
    return vsprintf($sql, $vals);
}

Sie können mit:

$query->getSQL();

Wenn Sie MySQL verwenden, können Sie Workbench mit SQL-Anweisungen anzuzeigen. Sie können Gebrauch sehen die laufende Abfrage von MySQL auch durch die folgende Verwendung:

 SHOW FULL PROCESSLIST \G

Vielleicht kann es nützlich sein, für jemanden:

// Printing the SQL with real values
$vals = $query->getFlattenedParams();
foreach(explode('?', $query->getSqlQuery()) as $i => $part) {
    $sql = (isset($sql) ? $sql : null) . $part;
    if (isset($vals[$i])) $sql .= $vals[$i];
}

echo $sql;
Solution:1
====================================================================================

function showQuery($query)
{
    return sprintf(str_replace('?', '%s', $query->getSql()), $query->getParams());
}

// call function  
echo showQuery($doctrineQuery);

Solution:2
====================================================================================

function showQuery($query)
{
    // define vars              
    $output    = NULL;
    $out_query = $query->getSql();
    $out_param = $query->getParams();

    // replace params
   for($i=0; $i<strlen($out_query); $i++) {
       $output .= ( strpos($out_query[$i], '?') !== FALSE ) ? "'" .str_replace('?', array_shift($out_param), $out_query[$i]). "'" : $out_query[$i];
   }

   // output
   return sprintf("%s", $output);
}

// call function  
echo showQuery($doctrineQueryObject);

Ich schrieb einen einfachen Logger, die mit eingefügten Parameter log Abfrage kann. Installation:

composer require cmyker/doctrine-sql-logger:dev-master

Verbrauch:

$connection = $this->getEntityManager()->getConnection(); 
$logger = new \Cmyker\DoctrineSqlLogger\Logger($connection);
$connection->getConfiguration()->setSQLLogger($logger);
//some query here
echo $logger->lastQuery;
$sql = $query->getSQL();

$parameters = [];
    foreach ($query->getParameters() as $parameter) {
        $parameters[] = $parameter->getValue();
    }

$result = $connection->executeQuery($sql, $parameters)
        ->fetchAll();

Modifizierte @dsamblas zur Arbeit funktionieren, wenn Parameter Datumsstrings wie dieses ‚2019.01.01‘ sind und wenn es Array IN wie geben

$qb->expr()->in('ps.code', ':activeCodes'),

. Also alles, was dsamblas schrieb, aber ersetzen startQuery mit diesem oder um die Unterschiede sehen und meinen Code hinzufügen. (Im Fall modifizierte er etwas in seiner Funktion und meine Version keine Änderungen).

public function startQuery($sql, array $params = null, array $types = null)

{
    if($this->isLoggable($sql)){
        if(!empty($params)){
            foreach ($params as $key=>$param) {

                try {
                    $type=Type::getType($types[$key]);
                    $value=$type->convertToDatabaseValue($param,$this->dbPlatform);
                } catch (Exception $e) {
                    if (is_array($param)) {
                        // connect arrays like ("A", "R", "C") for SQL IN
                        $value = '"' . implode('","', $param) . '"';
                    } else {
                        $value = $param; // case when there are date strings
                    }
                }

                $sql = join(var_export($value, true), explode('?', $sql, 2));
            }

        }
        echo $sql . " ;".PHP_EOL;
    }
}

Haben nicht viel testen.

Um eine SQL-Abfrage in Lehre auszudrucken, zu verwenden:

$query->getResult()->getSql();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top