(圖片來源)
紀錄 SQL Query 的兩種方式:
1. $query->tosql();
2. DB::getQueryLog();
1. 第一個方式 tosql()
適用 ORM 的 SQL 語法儲存於 $query 變數中這種寫法,當然變數名可自行定義。
$query = DB::table('scan'); $query->select('scan.id', 'scan.title', 'scan.scan_cate', 'scan.show_date', 'scan.writer_id', 'scan.counter'); if (!empty($data['keyword'])) { $query->where('scan.title', 'LIKE', '%' . $data['keyword'] . '%'); } $query->orderBy('show_date', 'desc'); $scans = $query->limit(300)->get(); $stringSql = $query->tosql(); echo $stringSql;
這種取出 SQL Query 的方式,結果會是單一字串,如下:
select `scan`.`id`, `scan`.`title`, `scan`.`scan_cate`, `scan`.`show_date`, `scan`.`writer_id`, `scan`.`counter` from `scan` where `scan`.`title` LIKE ? order by `show_date` desc limit 300 |
2. 第二個方式 DB::getQueryLog()
適用取得多個 Query 語法,取出結果會是多維陣列的形式,這種方式比較不同的地方是它除了 Query 字串還包含相關參數與執行時間等資訊,如下。
array(2) { [0]=> array(3) { ["query"]=> string(263) "select `scan`.`id`, `scan`.`title`, `scan`.`scan_cate`, `scan`.`show_date`, `scan`.`writer_id`, `scan`.`counter` from `scan` where `scan`.`title` LIKE ? and `scan`.`show_date` between ? and ? order by `show_date` desc limit 300" ["bindings"]=> array(3) { [0]=> string(6) "%test%" [1]=> string(10) "2017-09-10" [2]=> string(10) "2017-09-13" } ["time"]=> float(73.97) } [1]=> array(3) { ["query"]=> string(263) "select `scan`.`id`, `scan`.`title`, `scan`.`scan_cate`, `scan`.`show_date`, `scan`.`writer_id`, `scan`.`counter` from `scan` where `scan`.`title` LIKE ? and `scan`.`show_date` between ? and ? order by `show_date` desc limit 300" ["bindings"]=> array(3) { [0]=> string(6) "%test%" [1]=> string(10) "2017-09-10" [2]=> string(10) "2017-09-13" } ["time"]=> float(20.73) } }
但這兩種方式有共同的缺點,就是 Query 字串都不是可以直接拿來執行的 SQL 語法,相信眼尖的各位有發現 Query 字串中都有 ? 字元的存在,這是因為 Laravel 本身 ORM 的處理方式所造成的,那要如何產出可以原始且可以執行的 Query 語法呢?
我這邊有實作一個 function 來做 ? 字元的取代處理,相關程式碼如下:
/** * 取得當前的 query string * @return string * @date 2017-09-08T10:32:43+0800 */ public static function getQueryString() { $queryLog = DB::getQueryLog(); $lastQuery = end($queryLog); $stringSql = $lastQuery['query']; // 取代所有問號 $stringSql = preg_replace("/\?/", "'?'", $stringSql); // query 重組 foreach( $lastQuery['bindings'] as $arg ) { $stringSql = preg_replace("/\?/", $arg, $stringSql, 1); } return $stringSql; }
參考:
Get the last query executed in Laravel
Debugging Queries in Laravel
文章標籤
全站熱搜
留言列表