是否可以从Phalcon中的查询构建器实例中提取原始sql查询?像这样的东西?
$queryBuilder = new Phalcon\Mvc\Model\Query\Builder();
$queryBuilder
->from(…)
->where(…);
$rawSql = $queryBuilder->hypotheticalGetRawQueryMethod();
答案 0 :(得分:14)
错误和审判下面似乎有效。如果有人能确认是否有更好的方法,那就太好了。
$queryBuilder = new Builder();
$queryBuilder->from(…)->where(…);
$intermediate = $queryBuilder->getQuery()->parse();
$dialect = DI::getDefault()->get('db')->getDialect();
$sql = $dialect->select($intermediate);
修改:从2.0.3开始,您可以做到非常简单,有关详细信息,请参阅comment:
$modelsManager->createBuilder()
->from('Some\Robots')
->getQuery()
->getSql()
答案 1 :(得分:2)
您可以在DbAdapter上使用getRealSqlStatement()(或类似的函数名称)。见http://docs.phalconphp.com/en/latest/api/Phalcon_Db_Adapter.html
根据文档,你可以通过这种方式得到sql查询。
或等等,这可能不适用于querybuilder。否则,您可以设置低级查询日志记录:http://docs.phalconphp.com/en/latest/reference/models.html#logging-low-level-sql-statements
答案 2 :(得分:1)
$db = Phalcon\DI::getDefault()->getDb();
$sql = $db->getSQLStatement();
$vars = $db->getSQLVariables();
if ($vars) {
$keys = array();
$values = array();
foreach ($vars as $placeHolder=>$var) {
// fill array of placeholders
if (is_string($placeHolder)) {
$keys[] = '/:'.ltrim($placeHolder, ':').'/';
} else {
$keys[] = '/[?]/';
}
// fill array of values
// It makes sense to use RawValue only in INSERT and UPDATE queries and only as values
// in all other cases it will be inserted as a quoted string
if ((strpos($sql, 'INSERT') === 0 || strpos($sql, 'UPDATE') === 0) && $var instanceof \Phalcon\Db\RawValue) {
$var = $var->getValue();
} elseif (is_null($var)) {
$var = 'NULL';
} elseif (is_numeric($var)) {
$var = $var;
} else {
$var = '"'.$var.'"';
}
$values[] = $var;
}
$sql = preg_replace($keys, $values, $sql, 1);
}
您可以阅读there
答案 3 :(得分:0)
如果您使用的是查询生成器,则如下所示,然后getPhql
函数可以达到phalcon 3.4.4版本的目的。
$queryBuilder = new Builder();
$queryBuilder->from(…)->where(…)->getQuery();
$queryBuilder->getPhql();
答案 4 :(得分:0)
if (!function_exists("getParsedBuilderQuery")) {
/**
* @param \Phalcon\Mvc\Model\Query\BuilderInterface $builder
*
* @return null|string|string[]
*/
function getParsedBuilderQuery (\Phalcon\Mvc\Model\Query\BuilderInterface $builder) {
$dialect = Phalcon\Di::getDefault()->get('db')->getDialect();
$sql = $dialect->select($builder->getQuery()->parse());
foreach ($builder->getQuery()->getBindParams() as $key => $value) {
// For strings work fine. You can add other types below
$sql = preg_replace("/:?\s?($key)\s?:?/","'$value'",$sql);
}
return $sql;
}
}
我用于调试的简单函数。
答案 5 :(得分:0)
以下是常见的解决方案:
$result = $modelsManager->createBuilder()
->from(Foo::class)
->where('slug = :bar:', ['bar' => "some-slug"])
->getQuery()
->getSql();
但是您可能不希望看到没有查询值的查询,例如:
die(print_r($result, true));
Array
(
[sql] => SELECT `foo`.`id`, `foo`.`slug` FROM `foo` WHERE `foo`.`slug` = :bar
[bind] => Array
(
[bar] => some-slug
)
[bindTypes] =>
)
因此,这段简单的代码可能会有用:
public static function toSql(\Phalcon\Mvc\Model\Query\BuilderInterface $builder) : string
{
$data = $builder->getQuery()->getSql();
['sql' => $sql, 'bind' => $binds, 'bindTypes' => $bindTypes] = $data;
$finalSql = $sql;
foreach ($binds as $name => $value) {
$formattedValue = $value;
if (\is_object($value)) {
$formattedValue = (string)$value;
}
if (\is_string($formattedValue)) {
$formattedValue = sprintf("'%s'", $formattedValue);
}
$finalSql = str_replace(":$name", $formattedValue, $finalSql);
}
return $finalSql;
}