Wydrukuj zapytanie zbudowane za pomocą db_select ()

61

Chcę wydrukować zapytanie zbudowane za pomocą db_select () w sposób programowy. Czy jest jakaś funkcja API zapewniana przez Drupal Abstraction Layer?
Jest podobny do wyniku zapytania w Widoku, ale chcę go wydrukować z mojego modułu niestandardowego w celu debugowania.

Sithu
źródło

Odpowiedzi:

67

SelectQueryimplementuje SelectQuery::__toString(), który jest wywoływany w kontekstach, w których wymagany jest ciąg.

Rozważ następujący kod.

global $theme_key;

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

print $query;

Jego wynik jest następujący.

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

Aby uzyskać tablicę argumentów używanych dla zapytania, możesz wywołać SelectQuery::arguments().

Poniższy kod drukuje zapytanie i jego argumenty za pomocą funkcji udostępnionych z modułu Devel.

global $theme_key;

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

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

zrzut ekranu

Moduł Devel nie jest jednak konieczny i można drupal_set_message()wyświetlić wynik. Na przykład można użyć następującej funkcji, aby uzyskać ciąg znaków z symbolami zastępczymi zastąpionymi przez ich rzeczywiste wartości.

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

Poprzedni przykładowy kod, który pokazałem, stałby się następującym.

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

Zauważ, że SelectQuery::arguments()zwraca tablicę argumentów zapytań tylko wtedy, gdy jest ona wywoływana po SelectQuery::__toString(), SelectQuery::compile()lub SelectQuery::execute(); w przeciwnym razie SelectQuery::arguments()zwraca NULL.

Możesz użyć funkcji podobnej do poniższej, aby uzyskać zapytanie łańcuchowe, z symbolami zastępczymi zastąpionymi argumentami.

kiamlaluno
źródło
1
Myślę, że taka funkcja _get_query_string()powinna być częścią SelectQueryinterfejsu.
dashohoxha
46

Możesz użyć dpq (), aby wyświetlić zapytanie, i dpr (), aby wyświetlić wynik.

  $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
źródło
1
Zauważ, że wymaga to zainstalowania modułu Devel. Jeśli używasz Devel (uwielbiam to), jest to najłatwiejszy sposób.
joe_flash
2
dpq () gdzie byłeś całe moje życie!
Lomax
Nie wydaje się działać w try catchbloku, gdy zapytanie nie powiedzie się. W moim przypadku nie jest to pomocne, jeśli nie mogę debugować uszkodzonego zapytania.
Kiee
19

Inną opcją jest:

global $theme_key;

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

print strtr((string) $query, $query->arguments());
vijaycs85
źródło
2
Rzeczywiście krótkie i zwięzłe.
dashohoxha
2
Nie są wymagane żadne moduły nadymające / zewnętrzne. Dodatkowo działa to na zapytania, które nie zostały wykonane, dzięki czemu można wydrukować zapytanie, które się nie powiedzie i dpqspowoduje błąd, wydaje się , że nie pozwala na to nawet podczas try / catch.
Kiee
1
To powinna być poprawna odpowiedź.
albertski
8

Powyższe odpowiedzi są dobre, jeśli masz zainstalowany i skonfigurowany program Devel.

Najlepszym sposobem wydrukowania zapytania bez Devel jest jak poniżej.

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

Możemy użyć jednego z powyższych sposobów wydrukowania zapytania.

KiranD
źródło
4

Mam dobre rozwiązanie, które możesz skopiować / wkleić ciąg zapytania bezpośrednio w sekcji „SQL” w Phpmyadmin i debugować zapytanie (często używam tej metody, gdy mam problem z zapytaniem)

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

Mam nadzieję, że będzie to przydatne dla innych facetów.

Yusef Mohamadi
źródło