In truy vấn được xây dựng bằng db_select ()


61

Tôi muốn in truy vấn được xây dựng bằng db_select () theo cách lập trình. Có bất kỳ chức năng API nào được cung cấp bởi Lớp trừu tượng Drupal không?
Nó tương tự như đầu ra truy vấn trong Chế độ xem, nhưng tôi muốn in nó từ mô-đun tùy chỉnh của mình cho mục đích gỡ lỗi.

Câu trả lời:


67

SelectQuerythực hiện SelectQuery::__toString(), được gọi trong bối cảnh yêu cầu một chuỗi.

Hãy xem xét các mã sau đây.

global $theme_key;

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

print $query;

Đầu ra của nó là một trong những sau đây.

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

Để có được các mảng đối số được sử dụng cho truy vấn, bạn có thể gọi SelectQuery::arguments().

Đoạn mã sau in ra truy vấn và các đối số của nó bằng cách sử dụng các hàm có sẵn từ mô-đun Devel.

global $theme_key;

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

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

ảnh chụp màn hình

Tuy nhiên, mô-đun Devel không cần thiết và bạn có thể drupal_set_message()hiển thị đầu ra. Ví dụ: bạn có thể sử dụng hàm sau để lấy chuỗi có trình giữ chỗ được thay thế bằng giá trị thực của chúng.

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

Mã ví dụ trước tôi đã hiển thị sẽ trở thành mã sau.

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

Chú ý rằng SelectQuery::arguments()trả về mảng các đối số truy vấn chỉ khi nó được gọi sau SelectQuery::__toString(), SelectQuery::compile()hoặc SelectQuery::execute(); nếu không, SelectQuery::arguments()trả lại NULL.

Bạn có thể sử dụng một hàm tương tự như hàm sau để lấy truy vấn chuỗi, với các phần giữ chỗ được thay thế bằng các đối số.


1
Tôi nghĩ rằng một chức năng như _get_query_string()lẽ ra phải là một phần của SelectQuerygiao diện.
dashohoxha

46

Bạn có thể sử dụng dpq () để hiển thị truy vấn và dpr () để hiển thị kết quả.

  $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
Lưu ý rằng điều này đòi hỏi mô-đun Devel phải được cài đặt. Nếu bạn sử dụng Devel (tôi thích nó), đây là cách dễ nhất để đi.
joe_flash

2
dpq () nơi bạn đã là tất cả cuộc sống của tôi!
Lomax

Không xuất hiện để làm việc trong một try catchkhối khi truy vấn không thành công. Vì vậy, không hữu ích trong trường hợp của tôi nếu tôi không thể gỡ lỗi truy vấn bị hỏng.
Kiee

19

Một lựa chọn khác là:

global $theme_key;

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

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

2
Ngắn gọn và súc tích thực sự.
dashohoxha

2
Không có mô-đun bên thứ ba / yêu cầu. Ngoài ra, điều này hoạt động trên các truy vấn chưa được thực hiện, do đó bạn có thể in một truy vấn không thành công và báo lỗi, dpqdường như không cho phép điều này ngay cả trong một lần thử / bắt.
Kiee

1
Đây phải là câu trả lời chính xác.
albertski

8

Các câu trả lời trên là tốt khi bạn đã cài đặt và cấu hình Devel.

Cách tốt nhất để in truy vấn mà không có Devel như dưới đây.

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

Chúng ta có thể sử dụng một trong những cách trên để in truy vấn.


4

Tôi có một giải pháp tốt là bạn có thể sao chép / dán chuỗi truy vấn của mình trực tiếp trong phần "SQL" trong Phpmyadmin và gỡ lỗi truy vấn của bạn (Tôi thường sử dụng phương pháp này khi tôi vật lộn với truy vấn)

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

Tôi hy vọng điều này sẽ hữu ích cho những người khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.