Cetak kueri yang dibangun menggunakan db_select ()

61

Saya ingin mencetak kueri yang dibangun menggunakan db_select () secara terprogram. Apakah ada fungsi API yang disediakan oleh Drupal Abstraction Layer?
Ini mirip dengan hasil kueri dalam Tampilan, tetapi saya ingin mencetaknya dari modul khusus saya untuk tujuan debugging.

Sithu
sumber

Jawaban:

67

SelectQuerymengimplementasikan SelectQuery::__toString(), yang disebut dalam konteks di mana string diperlukan.

Pertimbangkan kode berikut.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print $query;

Keluarannya adalah sebagai berikut.

SELECT block.*
FROM 
{block} block
WHERE  (theme = :db_condition_placeholder_0) AND (status = :db_condition_placeholder_1)

Untuk mendapatkan berbagai argumen yang digunakan untuk kueri, Anda bisa menelepon SelectQuery::arguments().

Kode berikut mencetak kueri dan argumennya menggunakan fungsi yang tersedia dari modul Devel.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

dpm((string) $query);
dpm($query->arguments());

tangkapan layar

Modul Devel tidak perlu, dan Anda bisa drupal_set_message()menampilkan hasilnya. Misalnya, Anda bisa menggunakan fungsi berikut untuk mendapatkan string dengan placeholder diganti dengan nilai aktualnya.

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

Contoh kode sebelumnya yang saya tunjukkan akan menjadi yang berikut.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

drupal_set_message(format_string('Query: %query', array('%query' => _get_query_string($query))));

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

Perhatikan bahwa SelectQuery::arguments()mengembalikan array argumen permintaan hanya ketika dipanggil setelah SelectQuery::__toString(), SelectQuery::compile()atau SelectQuery::execute(); jika tidak, SelectQuery::arguments()kembali NULL.

Anda bisa menggunakan fungsi yang mirip dengan yang berikut ini untuk mendapatkan kueri string, dengan placeholder diganti dengan argumen.

kiamlaluno
sumber
1
Saya pikir fungsi seperti _get_query_string()seharusnya menjadi bagian dari SelectQueryantarmuka.
dashohoxha
46

Anda dapat menggunakan dpq () untuk menampilkan kueri, dan dpr () untuk menampilkan hasilnya.

  $query = db_select('users','u');
  $query->fields('u');
  $query->condition('u.uid', 1042);
  $result = $query->execute()->fetchAll();

  dpq($query); // Display the query. 
  dpr($result); // Display the query result.
umesh
sumber
1
Perhatikan bahwa ini membutuhkan modul Devel untuk diinstal. Jika Anda menggunakan Devel (I love it), ini adalah cara termudah untuk pergi.
joe_flash
2
dpq () di mana saja kamu selama hidupku!
Lomax
Tampaknya tidak berfungsi di try catchblok ketika kueri gagal. Jadi tidak membantu dalam kasus saya jika saya tidak dapat men-debug permintaan yang rusak.
Kiee
19

Pilihan lain adalah:

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print strtr((string) $query, $query->arguments());
vijaycs85
sumber
2
Pendek dan ringkas memang.
dashohoxha
2
Tidak perlu modul mengasapi / pihak ke-3. Plus ini berfungsi pada kueri yang belum dieksekusi, sehingga Anda dapat mencetak kueri yang gagal dan memberikan kesalahan, dpqtampaknya tidak mengizinkan ini bahkan dalam coba / tangkap.
Kiee
1
Ini seharusnya jawaban yang benar.
albertski
8

Jawaban di atas baik ketika Anda telah menginstal dan mengkonfigurasi Devel.

Cara terbaik untuk mencetak kueri tanpa Devel adalah seperti di bawah ini.

$query = db_select('block')
->condition('theme', $theme_key)
->condition('status', 1)
->fields('block');
//One way
echo $query->__toString();
// Second way
echo (string)$query;

Kami dapat menggunakan salah satu cara di atas untuk mencetak kueri.

KiranD
sumber
4

Saya punya solusi bagus yang bisa Anda salin / tempel string kueri Anda langsung di bagian "SQL" di Phpmyadmin dan debug permintaan Anda (saya sering menggunakan metode ini ketika saya berjuang dengan permintaan)

$querystring=$query->__toString();
$querystring=str_replace("{",'',$querystring);
$querystring=str_replace("}",'',$querystring);
foreach($query->getArguments() as $key=> $item){

    if(!$item) {
        $item = 'NULL';
    }
    $querystring=str_replace($key.')',$item.')',$querystring);
}
dpm($querystring);

Saya harap ini bermanfaat bagi orang lain.

Yusef Mohamadi
sumber