我们使用Doctrine,一个PHP ORM。我创建了一个这样的查询:

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

然后在函数中,我添加了各种where子句和适当的东西,像这样

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

稍后,在execute()-ing该查询对象之前,我想打印出原始SQL以检查它,并这样做:

$q->getSQLQuery();

但是,这只打印准备好的语句,而不是完整的查询。我想看看它正在发送什么到MySQL,但相反,它正在打印一个准备好的语句,包括?是否有一些方法可以看到'full'查询?


当前回答

你可以使用:

$query->getSQL();

如果您正在使用MySQL,您可以使用Workbench查看正在运行的SQL语句。 你也可以使用下面的命令查看mysql中正在运行的查询:

 SHOW FULL PROCESSLIST \G

其他回答

没有其他真正的查询,这就是预处理语句的工作方式。这些值绑定在数据库服务器中,而不是应用程序层。

看到我对这个问题的回答:在PHP与PDO,如何检查最终的SQL参数化查询?

(为了方便起见,这里重复一遍:)

使用带参数化值的准备语句不仅仅是动态创建SQL字符串的另一种方法。在数据库中创建一个准备好的语句,然后单独发送参数值。 所以发送到数据库的可能是一个PREPARE…,然后SET…最后执行.... 你将无法获得一些SQL字符串,如SELECT * FROM…,即使它会产生相同的结果,因为没有这样的查询实际上发送到数据库。

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

Doctrine并不是向数据库服务器发送一个“真正的SQL查询”:它实际上是使用准备好的语句,这意味着:

发送语句,以便对其进行准备(这是$query->getSql()返回的内容) 然后,发送参数(由$query->getParameters()返回) 执行准备好的语句

这意味着PHP端从来没有一个“真正的”SQL查询——因此Doctrine无法显示它。

你可以检查你的应用执行的查询,如果你把所有的查询都记录在mysql中:

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

会有更多的查询,不仅是一个你正在寻找,但你可以grep它。

->getSql();作品

编辑:

查看我使用的所有mysql查询

sudo vim /etc/mysql/my.cnf 

加上这两行:

general_log = on
general_log_file = /tmp/mysql.log

重新启动mysql

编辑2 如果你没有找到mysql的配置(它可以在很多地方),只需从mysql命令行设置这些变量。

mysql -u root -p 

SHOW VARIABLES LIKE 'general_log_file';
SHOW VARIABLES LIKE 'general_log';

SET GLOBAL general_log = 'on';
SET GLOBAL general_log_file = '/tmp/mysql.log';

//view the queries
sudo tail -f /tmp/mysql.log

这些设置的生命周期直到MySQL重新启动。或者是笔记本电脑。所以他们不是永久的-这在我看来是伟大的-我只需要他们当我调试时,我不需要担心编辑配置然后删除他们。如果您不删除日志记录,如果您忘记它,它可能会增长太多。

我的解决方案:

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

用法示例:

$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());