Gibt die Abfrage aus, die mit db_select () erstellt wurde

61

Ich möchte die Abfrage, die mit db_select () erstellt wird, auf programmatische Weise drucken . Gibt es eine API-Funktion, die von Drupal Abstraction Layer bereitgestellt wird?
Es ähnelt dem Abfragen von Ausgaben in Ansichten, aber ich möchte es zu Debugging-Zwecken aus meinem benutzerdefinierten Modul drucken.

Sithu
quelle

Antworten:

67

SelectQueryimplementiert SelectQuery::__toString(), was in den Kontexten aufgerufen wird, in denen ein String erforderlich ist.

Betrachten Sie den folgenden Code.

global $theme_key;

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

print $query;

Seine Ausgabe ist die folgende.

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

Um das Array der für die Abfrage verwendeten Argumente abzurufen, können Sie Folgendes aufrufen SelectQuery::arguments().

Der folgende Code druckt die Abfrage und ihre Argumente mit den im Modul Devel verfügbaren Funktionen.

global $theme_key;

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

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

Bildschirmfoto

Das Devel-Modul ist jedoch nicht erforderlich, und Sie können drupal_set_message()die Ausgabe anzeigen . Sie können beispielsweise die folgende Funktion verwenden, um eine Zeichenfolge abzurufen, bei der die Platzhalter durch ihre tatsächlichen Werte ersetzt werden.

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

Der vorherige Beispielcode, den ich gezeigt habe, würde der folgende sein.

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

Beachten Sie, dass SelectQuery::arguments()die Anordnung der Abfrage Argumente nur zurückgibt , wenn es nach aufgerufen wird SelectQuery::__toString(), SelectQuery::compile()oder SelectQuery::execute(); Andernfalls wird SelectQuery::arguments()zurückgegeben NULL.

Sie können eine Funktion verwenden, die der folgenden ähnlich ist, um die Zeichenfolgenabfrage abzurufen, wobei die Platzhalter durch die Argumente ersetzt werden.

kiamlaluno
quelle
1
Ich denke, dass eine Funktion wie _get_query_string()ein Teil der SelectQuerySchnittstelle gewesen sein sollte.
Dashohoxha
46

Sie können dpq () verwenden , um die Abfrage anzuzeigen, und dpr () , um das Ergebnis anzuzeigen.

  $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
quelle
1
Beachten Sie, dass hierfür das Devel-Modul installiert sein muss. Wenn Sie Devel verwenden (ich liebe es), ist dies der einfachste Weg.
Joe_flash
2
dpq () wo warst du mein ganzes Leben lang?
Lomax
Scheint nicht in einem try catchBlock zu funktionieren , wenn die Abfrage fehlschlägt. In meinem Fall also nicht hilfreich, wenn ich die fehlerhafte Abfrage nicht debuggen kann.
Kiee
19

Eine andere Option ist:

global $theme_key;

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

print strtr((string) $query, $query->arguments());
vijaycs85
quelle
2
Kurz und prägnant.
Dashohoxha
2
Kein Aufblähen / 3rd Party Module erforderlich. Dies funktioniert auch bei nicht ausgeführten Abfragen. Sie können also eine Abfrage drucken, die fehlschlägt und einen Fehler dpqausgibt. Dies scheint selbst bei einem Versuch / Fang nicht zuzulassen.
Kiee
1
Dies sollte die richtige Antwort sein.
Albertski
8

Die obigen Antworten sind gut, wenn Sie Devel installiert und konfiguriert haben.

Der beste Weg, die Abfrage ohne Devel zu drucken, ist der folgende.

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

Wir können eine der oben genannten Möglichkeiten verwenden, um die Abfrage zu drucken.

KiranD
quelle
4

Ich habe eine gute Lösung, Sie können Ihre Abfragezeichenfolge direkt in den Abschnitt "SQL" in Phpmyadmin kopieren / einfügen und Ihre Abfrage debuggen (ich verwende diese Methode oft, wenn ich mit der Abfrage zu kämpfen habe).

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

Ich hoffe, das ist nützlich für andere Leute.

Yusef Mohamadi
quelle