You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel:如何在listen方法中统计受影响行数及修改列数?

获取Laravel中UPDATE/DELETE查询的修改列数(或受影响行数)

嘿,这个需求我刚好处理过,给你分享一下实现思路和代码!

首先要明确两个关键点:

  • UPDATE语句:确实存在「被修改的列数量」,也就是SQL中SET子句里的列个数
  • DELETE语句:它是删除行的操作,并不会修改任何列,所以这里你可能是想获取被删除的行数(受影响行数),我会一起说明两种情况的实现方式。

实现代码

use Illuminate\Support\Facades\Log;

\DB::listen(function ($q) {
    $sql = strtolower(trim($q->sql));
    
    // 处理UPDATE类型查询
    if (str_starts_with($sql, 'update')) {
        // 正则匹配SET子句内容,兼容带WHERE/LIMIT的情况
        preg_match('/set\s+(.*?)\s+(where|limit|$)/i', $sql, $matches);
        
        if (isset($matches[1])) {
            // 分割列项,避免把字符串值中的逗号误判为列分隔符
            $columnEntries = preg_split('/,(?=(?:[^"]*"[^"]*")*[^"]*$)/', $matches[1]);
            $modifiedColumnCount = count($columnEntries);
            
            // 记录到日志,你也可以改成自己的存储逻辑
            Log::info("UPDATE操作修改了 {$modifiedColumnCount} 个列", [
                '原始SQL' => $q->sql,
                '绑定参数' => $q->bindings,
                '执行时间' => $q->time . 'ms'
            ]);
        }
    } 
    // 处理DELETE类型查询
    elseif (str_starts_with($sql, 'delete')) {
        // DELETE操作获取受影响的行数(即被删除的行数)
        $affectedRows = $q->affected;
        
        Log::info("DELETE操作删除了 {$affectedRows} 行数据", [
            '原始SQL' => $q->sql,
            '绑定参数' => $q->bindings,
            '执行时间' => $q->time . 'ms'
        ]);
        
        // 如果确实需要强调「无修改列」,可以添加这条日志
        // Log::info("DELETE操作未修改任何列", ['SQL' => $q->sql]);
    }
});

关键细节说明

  • 查询类型判断:用str_starts_with配合转小写的SQL,避免大小写敏感问题(比如Update或DELETE开头的语句也能匹配)
  • UPDATE列数统计:
    • 用正则提取SET到WHERE/LIMIT/语句结尾之间的内容,确保只拿到列赋值部分
    • 分割列项时用的正则/(?=(?:[^"]*"[^"]*")*[^"]*$)/,可以跳过字符串值中的逗号(比如name = "Smith, Alice"这种情况不会被误分割)
  • DELETE受影响行数:Laravel的$q对象自带affected属性,直接就能拿到被删除的行数,非常方便

内容的提问来源于stack exchange,提问作者Sebastián Daza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:33:16