Doktrin - sadece hazırlanan statment, gerçek sql değil yazdırmak için?

8 Cevap php

Biz Doktrini, bir PHP ORM kullanarak ediyoruz. Ben böyle bir sorgu oluşturma:

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

ve daha sonra işlevinde ben çeşitli ekleyerek kulüpler gibi bu nerede, uygun hükümler ve işler

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

Daha sonra, execute() bu sorgu nesnesini-ing önce, bunu incelemek amacıyla ham SQL yazdırmak, ve bunu yapmak istiyorum:

$q->getSQLQuery();

Ancak bu sadece hazırlanmış deyimi değil, tam sorgu yazdırır. Ben MySQL gönderiyor ne görmek istiyorum, ama bunun yerine ? 'nin de dahil olmak üzere hazırlanan bildiri, dışarı yazdırıyor. 'Tam' sorgusu görmek için bazı yolu var mı?

8 Cevap

Doktrin veritabanı sunucusu için bir "gerçek SQL sorgusu" gönderme değil: aslında hazırlanmış deyimleri kullanıyor anlamına gelir:

  • Hazırlıklı olmak için, deyim gönderme
  • Ve sonra, parametreleri gönderme
  • ve hazırlanmış deyimleri yürütme

Böylece, Doktrin görüntüleyemezsiniz - Bu PHP tarafında bir "gerçek" SQL sorgusu asla demektir.

Eğer mysql tüm sorguları oturum açarsanız size app tarafından yürütülen sorguyu kontrol edebilirsiniz:

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

orada aradığınız bir değil sadece daha fazla sorgular olacak ama bunun için grep edebilirsiniz.

ancak genellikle -> getSql (); eserler

getSqlQuery() teknik tüm SQL komutu göstermek, ama siz de parametreleri görebilirsiniz zaman çok daha kullanışlı yapar.

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

Bu model daha yeniden yapmak için, Raw SQL from Doctrine Query Object de comments anlatıldığı güzel bir yaklaşım var.

Bir örnek ..

$qb = $this->createQueryBuilder('a');
$query=$qb->getQuery();

Göster SQL: $sql=$query->getSQL();

Göster Parametreler: $parameters=$query->getParameters();

Başka bir gerçek sorgu var, bu hazırlanmış tablolar nasıl olduğunu. Değerler değil uygulama katmanı olarak, veri tabanı sunucusunda bağlıdır.

http://stackoverflow.com/questions/1786322/in-php-with-pdo-how-to-check-the-final-sql-parametrized-query/1786449#1786449: Bu soruya cevabım bak

(Kolaylık için burada Tekrarlanan :)

Parametrised değerleri ile hazırlanmış deyimleri kullanarak sadece dinamik SQL bir dize oluşturmak için başka bir yol değildir. Sen veritabanına hazırlanmış bir açıklama oluşturun ve daha sonra tek başına parametre değerleri göndermek.

Bu nedenle muhtemelen ne veritabanına gönderilen bir PREPARE ..., sonra da SET ... ve son olarak EXECUTE .... olacak

Böyle bir sorgu hiç aslında veritabanına gönderildi çünkü eşdeğer sonuçlar üretecektir bile, SELECT * FROM ... gibi bazı SQL dizesini almak mümkün olmayacaktır.

Belki birisi için yararlı olabilir:

// 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;

Ben tam olarak bunu yapar, bir Doctrine2 Logger oluşturduk. Bu Doktrin 2 kendi veri türü conversors kullanarak değerlerle parametrized sql sorgusu "nemlendirir".

<?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;
    }
}

Usage Example:; The following peace of code will echo on standard output any INSERT,UPDATE,DELETE SQL sentences generated with $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
                        )
                    )
                );

Daha berrak çözelti:

 /**
 * 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);
}