พิมพ์แบบสอบถามที่สร้างขึ้นโดยใช้ db_select ()


61

ฉันต้องการพิมพ์แบบสอบถามที่สร้างขึ้นโดยใช้db_select ()ในทางโปรแกรม มีฟังก์ชั่น API ใดบ้างที่จัดทำโดย Drupal Abstraction Layer?
คล้ายกับเอาต์พุตคิวรีใน Views แต่ฉันต้องการพิมพ์จากโมดูลที่กำหนดเองเพื่อการดีบัก

คำตอบ:


67

SelectQueryการดำเนินการSelectQuery::__toString()ซึ่งจะเรียกว่าในบริบทที่จำเป็นต้องมีสตริง

พิจารณารหัสต่อไปนี้

global $theme_key;

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

print $query;

เอาท์พุทมันเป็นหนึ่งดังต่อไปนี้

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

SelectQuery::arguments()ที่จะได้รับอาเรย์ของการขัดแย้งที่ใช้สำหรับการค้นหาที่คุณสามารถโทรหา

รหัสต่อไปนี้พิมพ์แบบสอบถามและข้อโต้แย้งโดยใช้ฟังก์ชั่นที่มีให้จากโมดูล Devel

global $theme_key;

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

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

ภาพหน้าจอ

ไม่จำเป็นต้องมีโมดูล Devel และคุณสามารถdrupal_set_message()แสดงผลลัพธ์ได้ ตัวอย่างเช่นคุณสามารถใช้ฟังก์ชันต่อไปนี้เพื่อรับสตริงที่มีตัวยึดแทนที่ด้วยค่าจริง

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;
}

โค้ดตัวอย่างก่อนหน้านี้ที่ฉันแสดงจะกลายเป็นรหัสต่อไปนี้

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;
}

ขอให้สังเกตว่าSelectQuery::arguments()ส่งกลับอาร์เรย์ของการขัดแย้งแบบสอบถามเฉพาะเมื่อมีการเรียกว่าหลังจากSelectQuery::__toString(), SelectQuery::compile()หรือSelectQuery::execute(); มิฉะนั้นผลตอบแทนSelectQuery::arguments()NULL

คุณสามารถใช้ฟังก์ชั่นที่คล้ายกับฟังก์ชันต่อไปนี้เพื่อรับเคียวรีสตริงด้วยตัวยึดตำแหน่งที่แทนที่ด้วยอาร์กิวเมนต์


1
ฉันคิดว่าฟังก์ชั่นที่_get_query_string()ควรจะเป็นส่วนหนึ่งของSelectQueryอินเทอร์เฟซ
dashohoxha

46

คุณสามารถใช้dpq ()เพื่อแสดงแบบสอบถามและdpr ()เพื่อแสดงผลลัพธ์

  $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.

1
โปรดทราบว่านี่จะต้องติดตั้งโมดูล Devel หากคุณใช้ Devel (ฉันชอบมาก) นี่เป็นวิธีที่ง่ายที่สุดในการไป
joe_flash

2
dpq () คุณอยู่ที่ไหนมาทั้งชีวิตของฉัน!
Lomax

ดูเหมือนจะไม่ทำงานในtry catchบล็อกเมื่อแบบสอบถามล้มเหลว ดังนั้นจึงไม่มีประโยชน์ในกรณีของฉันหากฉันไม่สามารถดีบักแบบสอบถามที่เสียหาย
Kiee

19

ตัวเลือกอื่นคือ:

global $theme_key;

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

print strtr((string) $query, $query->arguments());

2
สั้นและรัดกุมแน่นอน
dashohoxha

2
ไม่ต้องมีโมดูลของ Bloat / 3rd party นอกจากนี้ยังใช้งานได้กับแบบสอบถามที่ยังไม่ได้ดำเนินการเพื่อให้คุณสามารถพิมพ์แบบสอบถามที่ล้มเหลวและให้ข้อผิดพลาดdpqดูเหมือนจะไม่อนุญาตให้แม้ในลอง / จับ
Kiee

1
นี่ควรเป็นคำตอบที่ถูกต้อง
albertski

8

คำตอบข้างต้นนั้นดีเมื่อคุณติดตั้งและกำหนดค่า Devel

วิธีที่ดีที่สุดในการพิมพ์แบบสอบถามโดยไม่มี Devel มีดังนี้

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

เราสามารถใช้วิธีใดวิธีหนึ่งข้างต้นเพื่อพิมพ์แบบสอบถาม


4

ฉันมีทางออกที่ดีที่คุณสามารถคัดลอก / วางสตริงการสืบค้นของคุณโดยตรงในส่วน "SQL" ใน Phpmyadmin และแก้ปัญหาการสืบค้นของคุณ (ฉันมักจะใช้วิธีนี้เมื่อฉันต่อสู้กับแบบสอบถาม)

$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);

ฉันหวังว่านี่จะเป็นประโยชน์สำหรับคนอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.