(圖片來源)
紀錄 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
文章標籤
全站熱搜
