37150038940_1520f95a76_z.jpg

(圖片來源)

紀錄 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 

arrow
arrow
    創作者介紹
    創作者 Mayuge 的頭像
    Mayuge

    工程的日子每天都很師

    Mayuge 發表在 痞客邦 留言(0) 人氣()