855 Stimmen

Wie kann ich den Abfrage-Generator dazu bringen, seine Roh-SQL-Abfrage als Zeichenfolge auszugeben?

Unter Verwendung des folgenden Codes:

DB::table('users')->get();

Möchte ich den Roh-SQL-Abfragestring erhalten, den der obige Datenbankabfrage-Generator erstellen wird. In diesem Beispiel wäre es SELECT * FROM users.

Wie mache ich das?

1124voto

Steven Mercatante Punkte 23557

Verwenden Sie die toSql()-Methode auf einer QueryBuilder-Instanz.

DB::table('users')->toSql() würde zurückgeben:

select * from `users`

Dies ist einfacher als das Verdrahten eines Ereignislisteners und ermöglicht es Ihnen auch, jederzeit zu überprüfen, wie die Abfrage tatsächlich aussieht, während Sie sie erstellen.

Hinweis: Diese Methode funktioniert für Query Builder oder Eloquent, jedoch wird toSql() anstelle von first() oder get() verwendet. Sie können die Abfrage nicht gleichzeitig ausführen und auch das SQL abrufen mithilfe dieser Methode.

1073voto

jfortunato Punkte 10657

Um die zuletzt ausgeführten Abfragen auf dem Bildschirm auszugeben, können Sie dies verwenden:

\DB::enableQueryLog(); // Aktiviere Abfrageprotokoll

// Ihre Eloquent-Abfrage wird ausgeführt, indem Sie get() verwenden

dd(\DB::getQueryLog()); // Zeige Ergebnisse des Protokolls

Ich glaube, dass die neuesten Abfragen am Ende des Arrays stehen werden.

Sie werden etwas wie das haben:

array(1) {
  [0]=>
  array(3) {
    ["query"]=>
    string(21) "select * from "users""
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    string(4) "0.92"
  }
}

(Danke an Joshuas Kommentar unten.)

186voto

Kakashi Punkte 3329

DB::QueryLog() funktioniert nur, nachdem Sie die Abfrage mit $builder->get() ausgeführt haben.

Wenn Sie die Rohabfrage vor oder ohne Ausführung der Abfrage erhalten möchten, können Sie die $builder->toSql() Methode verwenden.

Beispiel zum Abrufen des Roh-SQL und zum Ersetzen von '?' durch tatsächliche Bindewerte:

$query = str_replace(array('?'), array('\'%s\''), $builder->toSql());
$query = vsprintf($query, $builder->getBindings());
dump($query);

$result = $builder->get();

Oder Sie können absichtlich einen Fehler auslösen, zum Beispiel durch Verwendung einer nicht vorhandenen Tabelle oder Spalte. Dann können Sie die generierte Abfrage in der Ausnahmemeldung sehen.

66voto

Rubens Mariuzzo Punkte 26951

Sie können dem 'illuminate.query'-Ereignis zuhören. Fügen Sie vor der Abfrage den folgenden Ereignislistener hinzu:

Event::listen('illuminate.query', function($query, $params, $time, $conn) 
{ 
    dd(array($query, $params, $time, $conn));
});

DB::table('users')->get();

Dies wird etwas ähnliches ausgeben:

array(4) {
  [0]=>
  string(21) "select * from "users""
  [1]=>
  array(0) {
  }
  [2]=>
  string(4) "0.94"
  [3]=>
  string(6) "sqlite"
}

65voto

Luke Snowden Punkte 3700

Wenn Sie versuchen, das Log mit Illuminate ohne Laravel zu erhalten, verwenden Sie:

\Illuminate\Database\Capsule\Manager::getQueryLog();

Sie könnten auch schnell eine Funktion wie diese erstellen:

function logger()
{
    $queries = \Illuminate\Database\Capsule\Manager::getQueryLog();
    $formattedQueries = [];
    foreach ($queries as $query) :
        $prep = $query['query'];

        foreach ($query['bindings'] as $binding) :

            if (is_bool($binding)) {
                $val = $binding === true ? 'TRUE' : 'FALSE';
            } else if (is_numeric($binding)) {
                $val = $binding;
            } else {
                $val = "'$binding'";
            }

            $prep = preg_replace("#\?#", $val, $prep, 1);
        endforeach;
        $formattedQueries[] = $prep;
    endforeach;
    return $formattedQueries;
}

BEARBEITEN

Aktualisierte Versionen scheinen das Abfragenprotokollieren standardmäßig deaktiviert zu haben (das obige gibt ein leeres Array zurück). Um es wieder einzuschalten, wenn Sie den Capsule Manager initialisieren, holen Sie sich eine Instanz der Verbindung und rufen Sie die Methode enableQueryLog auf

$capsule::connection()->enableQueryLog();

ERNEUT BEARBEITEN

Unter Beachtung der eigentlichen Frage könnten Sie tatsächlich Folgendes tun, um die aktuelle einzelne Abfrage anstelle aller vorherigen Abfragen zu konvertieren:

$sql = $query->toSql();
$bindings = $query->getBindings();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X