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

如何在Laravel中获取已替换参数的INSERT语句原生SQL

解决方案

Laravel 提供的 compileInsert 方法本身仅生成参数化 SQL 模板,不会自动将绑定值替换到占位符中,你可以借助 PDO 实例的转义能力手动完成替换,避免生成的 SQL 存在语法错误或注入风险。

修改后的可运行代码如下:

Post::all()->each(function($post)
{
    $builder = DB::table('posts');
    // 定义插入的字段和对应值
    $insertData = [
        'created_at' => $post->created_at,
        'title' => $post->title
    ];
    // 生成参数化SQL模板
    $insertStatement = $builder->getGrammar()->compileInsert(
        $builder->select(array_keys($insertData)), 
        $insertData
    );

    // 用PDO对所有值做合法转义
    $pdo = DB::getPdo();
    $escapedBindings = array_map(function($value) use ($pdo) {
        return $pdo->quote($value);
    }, array_values($insertData));

    // 按顺序替换占位符生成最终SQL
    $realInsertSql = \Str::replaceArray('?', $escapedBindings, $insertStatement) . ';';

    Storage::disk('sql')->append('posts-latest.sql', $realInsertSql);
    dump($realInsertSql);
});

批量导出优化

如果需要导出全表数据,不需要逐行生成INSERT语句,可批量生成单条INSERT多行值的格式,大幅提升导出性能:

// 一次性取出所有需要导出的字段数据
$insertData = Post::query()->get(['created_at', 'title'])->toArray();
$builder = DB::table('posts');

// 生成批量插入的参数化SQL模板
$insertStatement = $builder->getGrammar()->compileInsert(
    $builder->select(array_keys($insertData[0])),
    $insertData
);

// 打平二维数组获取绑定值顺序,统一转义
$pdo = DB::getPdo();
$escapedBindings = collect($insertData)
    ->flatten()
    ->map(fn($value) => $pdo->quote($value))
    ->toArray();

// 替换占位符生成最终SQL
$realInsertSql = \Str::replaceArray('?', $escapedBindings, $insertStatement) . ';';
Storage::disk('sql')->put('posts-latest.sql', $realInsertSql);

注意事项

  • 上述方案会自动处理特殊字符转义,比如字段值包含单引号、特殊符号的场景,生成的SQL可直接在其他MySQL环境执行
  • 如未全局引入Str facade,可替换为完整命名空间 \Illuminate\Support\Str::replaceArray 调用

内容的提问来源于stack exchange,提问作者Zakalwe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:45:03