Laravel 打印输出模型执行的最终sql语句

一、框架自带打印sql语句存在的问题

Laravel 自带打印查询执行的sql的方法 toSql 和 加日志输出到 storage 目录

两种方式,打出的sql都是待执行的,即 bidings 参数没有替换到原生sql语句中,像下面两图一样:

 这种情况,简单sql还可以看看有没有存在问题

二、实际问题:

今天遇到一个相对复杂的业务场景,拼接多个whereRaw的sql语句,在程序里将执行sql(上图中的)打出来放到数据库执行,是可以拿到预期符合条件数据(如下图),但是程序执行,怎么都拿不到数据,很是奇怪

 三、解决方法:

看到上面sql在数据库执行完全没问题,于是猜测问题应该是laravel执行的语句有问题,就想方设法打印出最终执行sql,过程不再多说,直接看方法:

public function getFinalSql($query)
{
    $sql_str = $query->toSql();
    $bindings = $query->getBindings();

    $wrapped_str = str_replace('?', "'?'", $sql_str);

    return str_replace_array('?', $bindings, $wrapped_str);
}

在执行查询语句前,调用该方法,将返回结果打印,就可以看到框架模型最终执行的语句:

然后观察语句发现like时,框架给字符串自动拼接了引号转义符并且多加了一层 单引号,导致语句不正确,所以查询拿不到预期数据,修改后即可

四、打印接口全部查询sql:

一次打印出接口内执行的所有sql可以使用下面方法:

use Illuminate\Support\Facades\DB;

// 1. 启用查询日志
DB::enableQueryLog();

// 2. 执行查询

# 这里可以是很多查询逻辑

// 3. 获取查询日志
$queryLog = DB::getQueryLog();

// 4. 打印执行的 SQL 语句
foreach ($queryLog as $query) {
    echo $query['query'];
    echo "\n";
}

按上面在接口内查询语句前获取查询日志,在查询之后输出即可打印出查询逻辑执行的sql语句

打印出来即可看到如下图类似的sql语句

 可以看到sql语句中很多的?占位符,这给分析或者到数据库执行带来很大不便

所以可以对上面的打印sql地方进行更改优化,将占位符替换为执行时使用的具体值:

use Illuminate\Support\Facades\DB;

// 1. 启用查询日志
DB::enableQueryLog();

// 2. 执行查询

# 这里可以是很多查询逻辑

// 3. 获取查询日志
$queryLog = DB::getQueryLog();

// 4. 打印执行的 SQL 语句
foreach ($queryLog as $query) {
    $sql = str_replace('?', '%s', $query['query']);
    $bindings = array_map(function ($binding) {
        return is_numeric($binding) ? $binding : "'{$binding}'";
    }, $query['bindings']);
    $fullSql = vsprintf($sql, $bindings);
    echo $fullSql;
    echo "\n";
}

然后再打印看执行的sql如下图:

 已经ok,可以拿到具体执行的sql,这样就可以对接口执行的查询语句做具体分析了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值