Laravel 顯示 SQL 語法

在開發過程中,有時會需要查看 Laravel ORM 所產生的 SQL 語句,以便除錯或優化查詢。以下是幾種常見的方式來顯示 SQL:


🔍 使用 toSql()

  • 適用於 Illuminate\Database\Query\BuilderEloquent\Builder 的查詢鏈結。
  • 不會執行 SQL,只是取得 SQL 字串(佔位符為 ?,不包含綁定資料)。
  • 注意:不能對 Model 實體 使用 toSql(),否則會出現錯誤。
// 正確寫法:Query Builder
$sql = DB::table('products')->select('id', 'name')->toSql();

// 正確寫法:Eloquent 查詢鏈結
$sql = Product::where('id', 1)->toSql();

dd($sql); // select * from `products` where `id` = ?

❌ 錯誤寫法(會報錯):

Product::first()->toSql(); // ❌ 這裡是 Model 實體,不是查詢鏈

🧾 使用 DB::getQueryLog()

  • 可以查看實際執行過的 SQL 語句與綁定值。
  • 通常用於除錯目的,需搭配 DB::enableQueryLog() 使用。
  • 執行 SQL 後再 dd() 查看記錄。
use Illuminate\Support\Facades\DB;

DB::enableQueryLog();

// 執行任意查詢
Product::where('id', 1)->delete();

// 顯示查詢記錄
dd(DB::getQueryLog());

📌 備註:

  • 回傳為陣列,包含 SQL、bindings(參數)、time(耗時)。
  • 僅在同一請求中有效,建議於開發階段使用,不建議在 production 開啟。

✅ 建議替代方案:DB::listen()

若要更即時地監聽所有 SQL,可使用 DB::listen()

DB::listen(function ($query) {
    logger("SQL: {$query->sql}");
    logger("Bindings: " . implode(', ', $query->bindings));
    logger("Time: {$query->time}ms");
});

通常可寫在 AppServiceProviderboot() 方法中進行全域監聽。


參考文件