从 Phalcon 查询生成器获取原始 sql
Posted
技术标签:
【中文标题】从 Phalcon 查询生成器获取原始 sql【英文标题】:Get raw sql from Phalcon query builder 【发布时间】:2014-02-15 20:05:05 【问题描述】:是否可以从 Phalcon 中的查询构建器实例中提取原始 sql 查询?像这样?
$queryBuilder = new Phalcon\Mvc\Model\Query\Builder();
$queryBuilder
->from(…)
->where(…);
$rawSql = $queryBuilder->hypotheticalGetRawQueryMethod();
【问题讨论】:
【参考方案1】:您可以在 DbAdapter 上使用 getRealSqlStatement()(或类似的函数名称)。见http://docs.phalconphp.com/en/latest/api/Phalcon_Db_Adapter.html
根据文档,您可以通过这种方式获得生成的 sql 查询。
或者等一下,这可能不适用于查询构建器。否则,您可以设置低级查询日志记录:http://docs.phalconphp.com/en/latest/reference/models.html#logging-low-level-sql-statements
【讨论】:
【参考方案2】:通过错误和尝试,以下似乎有效。如果有人能确认是否有更好的方法,那就太好了。
$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()
【讨论】:
【参考方案3】:$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
【讨论】:
【参考方案4】:如果您使用的是查询生成器,那么如下所示,getPhql
函数可以根据 phalcon 3.4.4 版本达到目的。
$queryBuilder = new Builder();
$queryBuilder->from(…)->where(…)->getQuery();
$queryBuilder->getPhql();
【讨论】:
【参考方案5】: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;
我用来调试的简单函数。
【讨论】:
【参考方案6】:以下是常见的解决方案:
$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;
【讨论】:
以上是关于从 Phalcon 查询生成器获取原始 sql的主要内容,如果未能解决你的问题,请参考以下文章
我如何将 SQL 原始查询重写为 Laravel 查询生成器