Jak uzyskać konstruktora kwerend, aby wyświetlał surowe zapytanie SQL jako ciąg znaków?

544

Biorąc pod uwagę następujący kod:

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

Chcę uzyskać nieprzetworzony ciąg zapytania SQL, który wygeneruje powyższy konstruktor zapytań bazy danych. W tym przykładzie byłoby to SELECT * FROM users.

Jak mam to zrobic?

meiryo
źródło
14
Laravel Eloquent ORM dostaje surowe zapytanie:echo User::where('status', 1)->toSql();
Muhammad Shahzad
Korzystam z pakietu dla Laravel - Telescope, rejestruje wszystkie zapytania i robi wiele innych rzeczy.
vinsa

Odpowiedzi:

658

Aby wyświetlić na ekranie ostatnie uruchomione zapytania, możesz użyć tego:

DB::enableQueryLog(); // Enable query log

// Your Eloquent query executed by using get()

dd(DB::getQueryLog()); // Show results of log

Wierzę, że najnowsze zapytania będą na dole tablicy.

Będziesz miał coś takiego:

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

(Dzięki komentarzowi Jozuego poniżej.)

jfortunato
źródło
2
hmm nie jestem pewien, ale możesz osiągnąć to, co chcesz z pakietem kompozytora stackoverflow.com/a/17339752/813181
jfortunato
9
Może nawet lepiej jest LogLog::debug(DB::getQueryLog())
wypisać
35
Może być konieczne włączenie tej opcji, ponieważ teraz jest ona domyślnie wyłączona. Możesz użyć tego polecenia, aby włączyć je tymczasowo:DB::enableQueryLog();
Joshua Fricke
5
Próbowałem twojej odpowiedzi. Spróbowałem, DB::enableQueryLog(); dd(DB::getQueryLog());ale powraca tylko []...
Jestem najgłupszą osobą
6
Jeśli masz wiele baz danych, być może trzeba to zrobićDB::connection('database')->getQueryLog()
Damien Ó Ceallaigh,
744

Użyj toSql()metody dla QueryBuilderinstancji.

DB::table('users')->toSql() wróciłby:

wybierz * z `użytkowników`

Jest to łatwiejsze niż podłączenie detektora zdarzeń, a także pozwala sprawdzić, jak zapytanie będzie wyglądać w dowolnym momencie podczas jego budowania.

Steven Mercatante
źródło
6
Myślę, że jest to najłatwiejszy sposób, jeśli używasz Eloquent poza Laravel
Gab
8
@Stormsson Nie jest to możliwe, ponieważ PHP nigdy nie ma zapytania z powiązaniami zastąpionymi ich wartościami. Aby uzyskać wszystkie zapytania w całości, musisz je zalogować z MySQL. Tutaj jest więcej informacji: stackoverflow.com/questions/1786322/...
Matthew
40
@Stormsson możesz użyć getBindingsmetody. Spowoduje to zwrócenie powiązań w celu ich powiązania z instrukcją SQL.
danronmoon
2
Bardzo pomocne przy debugowaniu skomplikowanych zapytań, których Eloquent odmawia uruchomienia, ponieważ nie pojawiają się one w dzienniku zapytań.
BobChao87
33
Aby uzyskać zapytanie z bindinds$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
Ennio Sousa,
88

DB::QueryLog()działają tylko po wykonaniu zapytania $builder->get(). jeśli chcesz uzyskać zapytanie przed jego wykonaniem, możesz użyć $builder->toSql()metody. to jest przykład, jak uzyskać sql i powiązać go:

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

    $result = $builder->get();

LUB po prostu zrób błąd zapytania, np. Wywołanie nieistniejącej tabeli lub kolumny, zobaczysz wygenerowane zapytanie w wyjątku XD

Kakashi
źródło
3
To zdecydowanie najlepsza odpowiedź, prosta i prosta. Dzięki :)
Sobakus
18
Jako jeden liniowiec:$query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
kramer65
Powinno to zostać włączone do frameworka jako funkcja natywna. Dzięki
Tomáš Mleziva
Pamiętaj, że to nie zadziała, jeśli zapytanie ma już znaki procentowe, takie jak LIKEzapytanie lub podczas formatowania dat. Najpierw musisz uciec przed tymi z podwójnymi znakami procentowymi.
The Unknown Dev
Czy robiąc to, masz obawy związane z bezpieczeństwem? Czy wiązania są dezynfekowane $builder->getBindings()?
solidau
56

Możesz odsłuchać wydarzenie „illuminate.query”. Przed zapytaniem dodaj następujący detektor zdarzeń:

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

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

Spowoduje to wydrukowanie czegoś takiego:

array(4) {
  [0]=>
  string(21) "select * from "users""
  [1]=>
  array(0) {
  }
  [2]=>
  string(4) "0.94"
  [3]=>
  string(6) "sqlite"
}
Rubens Mariuzzo
źródło
1
Dostaję wezwanie do niezdefiniowanej metody Illuminate \ Database \ Query \ Builder :: listen () w Laravel 4
Miguel Stevens
2
Dzięki, to świetnie. Warto zauważyć, że dd jest funkcją, która generuje zrzut podanej zmiennej i kończy wykonywanie skryptu, a także, aby zaimportować Zdarzenie, touse Illuminate\Support\Facades\Event;
radtek
1
@radtek: Zamiast tego use Illuminate\Support\Facades\Event;możesz po prostu zrobić, use Event;ponieważ jest to fasada .
TachyonVortex,
50

Jeśli próbujesz uzyskać Dziennik za pomocą Podświetlania bez Laravela, użyj:

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

Możesz także skorzystać z szybkiej funkcji, takiej jak:

function logger() {
    $queries = \Illuminate\Database\Capsule\Manager::getQueryLog();
    $formattedQueries = [];
    foreach( $queries as $query ) :
        $prep = $query['query'];
        foreach( $query['bindings'] as $binding ) :
            $prep = preg_replace("#\?#", is_numeric($binding) ? $binding : "'" . $binding . "'", $prep, 1);
        endforeach;
        $formattedQueries[] = $prep;
    endforeach;
    return $formattedQueries;
}

EDYTOWAĆ

zaktualizowane wersje domyślnie mają wyłączone rejestrowanie zapytań (powyższe zwraca pustą tablicę). Aby włączyć ponownie, podczas inicjowania Capsule Managera, złap instancję połączenia i wywołaj enableQueryLogmetodę

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

EDYTUJ PONOWNIE

Biorąc pod uwagę rzeczywiste pytanie, można faktycznie wykonać następujące czynności, aby przekonwertować bieżące pojedyncze zapytanie zamiast wszystkich poprzednich zapytań:

$sql = $query->toSql();
$bindings = $query->getBindings();
Luke Snowden
źródło
otrzymuję ten typ zwrotu z zapytania „name = [{” name ”:„ rifat ”}]„ co muszę zrobić, aby uzyskać tylko „name = rifat”?
bezcielesny
Wydrukowałbym twoje wiązania, wygląda na to, że podajesz tablicę zamiast łańcucha
Luke Snowden
Jest to pomocny początek, ale wydaje się, że zaniedbuje się dodawanie pojedynczych cudzysłowów wokół sparametryzowanych wartości, na przykład gdy przekazuję ciąg podobny do 'US/Eastern'.
Ryan
1
@ Ryan to prawda, dlatego powiedziałem quick function. Wierzę, że podstawowy kod użyje metod przygotowawczych ( php.net/manual/en/mysqli.prepare.php ), dlatego właśnie ?wymagane są tylko te . Możesz php.net/manual/en/function.is-numeric.php, aby ustalić, czy dane wejściowe mają być zamknięte w pojedynczych cudzysłowach.
Luke Snowden
1
@LukeSnowden Twoja odpowiedź jest genialna! W końcu poświęciłem czas na wypróbowanie nowej wersji (którą edytowałem powyżej, aby uwzględnić Twój is_numericpomysł) i działa! Uwielbiam to. Dziękuję Ci.
Ryan,
36

Jest elokwentny sposób na uzyskanie ciągu zapytania.

toSql ()

w naszym przypadku,

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

powrót

select * from users

jest dokładne rozwiązanie, które zwraca ciąg zapytania SQL .. Mam nadzieję, że to pomocne ...

CelinVeronicca
źródło
11
co z powiązaniami zapytania? np. kiedy robisz ->where('foo', '=', 'bar')bar nie pokaże się w sql
Toskan
28
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
Kuldeep Mishra
źródło
Jest to o wiele bardziej precyzyjne, kontrolowane i spełnia potrzebę pytania.
benjaminhull
Dziękuję za Twój komentarz.
Kuldeep Mishra
2
Możesz dołączyć ->toSql()tak jak w przypadku, gdy po modelu jest więcej argumentów. np.User::where('id', 1)->toSql()
Toby Mellor
24

Jeśli używasz laravel 5.1 i MySQL, możesz skorzystać z tej funkcji:

/*
 *  returns SQL with values in it
 */
function getSql($model)
{
    $replace = function ($sql, $bindings)
    {
        $needle = '?';
        foreach ($bindings as $replace){
            $pos = strpos($sql, $needle);
            if ($pos !== false) {
                if (gettype($replace) === "string") {
                     $replace = ' "'.addslashes($replace).'" ';
                }
                $sql = substr_replace($sql, $replace, $pos, strlen($needle));
            }
        }
        return $sql;
    };
    $sql = $replace($model->toSql(), $model->getBindings());

    return $sql;
}

Jako parametr wejściowy możesz użyć jednego z nich

Podświetl \ Baza danych \ Elokwentny \ Konstruktor

Podświetl \ Baza danych \ Elokwentny \ Relacje \ HasMany

Podświetl \ Baza danych \ Zapytanie \ Konstruktor

Jewgienij Afanasiew
źródło
Poprawiono odpowiedź, uwzględniając wszystkie uwagi zawarte w komentarzach. Dziękuję Ci bardzo.
Jewgienij Afanasiew
13

Najpierw musisz włączyć dziennik zapytań, wywołując:

DB::enableQueryLog();

po zapytaniach za pomocą fasady DB możesz napisać:

dd(DB::getQueryLog());

wynik polubi się poniżej:

array:1 [▼
  0 => array:3 [▼
    "query" => "select * from `users` left join `website_user` on `users`.`id` = `website_user`.`user_id` left join `region_user` on `users`.`id` = `region_user`.`user_id` left ▶"
    "bindings" => array:5 [▶]
    "time" => 3.79
  ]
]
Ravi Mane
źródło
bardzo pomocna odpowiedź
Anoop PS
cześć, użyłem $ result = DB :: select ('select * z sqrt_user_modules gdzie user_id =: id', ['id' => $ user]); DB :: enableQueryLog (); ale nie otrzymałem żadnych danych wyjściowych dd (DB :: getQueryLog ());
Anoop PS,
czy musimy dołączyć jakąkolwiek bibliotekę
Anoop PS
1
Krok 1: DB :: enableQueryLog (); krok 2: $ wynik = DB :: select ('select * z sqrt_user_modules gdzie user_id =: id', ['id' => $ user]); krok 3: dd (DB :: getQueryLog ());
Ravi Mane
12

Jest to zdecydowanie najlepsze rozwiązanie, jakie mogę zaproponować każdemu do debugowania elokwentnego ostatniego zapytania lub zapytania końcowego, chociaż zostało to również omówione:

// query builder
$query = DB::table('table_name')->where('id', 1);

// binding replaced
$sql = str_replace_array('?', $query->getBindings(), $query->toSql());

// for laravel 5.8^
$sql = Str::replaceArray('?', $query->getBindings(), $query->toSql());

// print
dd($sql);
justnajm
źródło
10

Pierwszy sposób:

Po prostu możesz wykonać następujące czynności przy użyciu toSql()metody,

$query = DB::table('users')->get();

echo $query->toSql();

Jeśli to nie działa, możesz skonfigurować to z dokumentacji laravel .

Drugi sposób:

Innym sposobem na to jest

DB::getQueryLog()

ale jeśli zwróci pustą tablicę, domyślnie jest wyłączona, odwiedź to ,

po prostu włącz za pomocą DB::enableQueryLog() i będzie działać :)

Więcej informacji na stronie Github Issue wiedzieć więcej na ten temat.

Mam nadzieję, że to pomoże :)

Sagar Naliyapara
źródło
10

„Macroable” wymiana dostać zapytanie SQL z wiązaniami.

  1. Dodaj poniżej funkcję makra w metodzie.AppServiceProvider boot()

    \Illuminate\Database\Query\Builder::macro('toRawSql', function(){
        return array_reduce($this->getBindings(), function($sql, $binding){
            return preg_replace('/\?/', is_numeric($binding) ? $binding : "'".$binding."'" , $sql, 1);
        }, $this->toSql());
    });
  2. Dodaj alias do Eloquent Builder. ( Laravel 5.4+ )

    \Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
        return ($this->getQuery()->toRawSql());
    });
  3. Następnie debuguj jak zwykle. ( Laravel 5.4+ )

    Np. Konstruktor zapytań

    \Log::debug(\DB::table('users')->limit(1)->toRawSql())

    Np. Elokwentny konstruktor

    \Log::debug(\App\User::limit(1)->toRawSql());

Uwaga: od wersji Laravel 5.1 do 5.3, ponieważ Eloquent Builder nie korzysta z tej Macroablecechy, nie może dodawać toRawSqlaliasu do Eloquent Builder w locie. Postępuj zgodnie z poniższym przykładem, aby osiągnąć to samo.

Np. Eloquent Builder ( Laravel 5.1 - 5.3 )

\Log::debug(\App\User::limit(1)->getQuery()->toRawSql());
Ijas Ameenudeen
źródło
Ups, spóźniłem się. Po prostu chcę przesłać odpowiedź za pomocą makra. To najładniejsza odpowiedź. Powinna być zaakceptowana odpowiedź: D
nmfzone
Możesz go wyodrębnić w lunecie na podstawie Modelu
Ogier Schelvis
8

użyj pakietu debugbar

composer require "barryvdh/laravel-debugbar": "2.3.*"

wprowadź opis zdjęcia tutaj

panqingqiang
źródło
7

Od Laravel 5.2i dalej. możesz użyć DB::listendo wykonania wykonanych zapytań.

DB::listen(function ($query) {
    // $query->sql
    // $query->bindings
    // $query->time
});

Lub jeśli chcesz debugować pojedyncze Builderwystąpienie, możesz użyć toSqlmetody.

DB::table('posts')->toSql(); 
Zayn Ali
źródło
1
Funkcja nasłuchiwania jest przydatna, zadeklaruj ją przed uruchomieniem zapytania i zrzuć sql & powiązania w ramach metody. Niedoskonały, ale działa szybciej / łatwiej niż inne odpowiedzi.
Andrew
7

Najłatwiej jest popełnić celowy błąd . Na przykład chcę zobaczyć pełne zapytanie SQL następującej relacji:

 public function jobs()
        {
            return $this->belongsToMany(Job::class, 'eqtype_jobs')
                   ->withPivot(['created_at','updated_at','id'])
                   ->orderBy('pivot_created_at','desc');
        }

Chcę tylko, aby kolumna nie została znaleziona, tutaj wybieram created_ati zmieniłem ją created_ats, dodając trailing sto:

public function jobs()
            {
                return $this->belongsToMany(Job::class, 'eqtype_jobs')
                       ->withPivot(['created_ats','updated_at','id'])
                       ->orderBy('pivot_created_at','desc');
            }

Debuger zwróci następujący błąd:

(4/4) ErrorException SQLSTATE [42S22] Kolumna nie znaleziono: 1054 nieznany kolumna eqtype_jobs.created_ats "w polu 'liście' (SQL: wybierz jobs*,. eqtype_jobs, set_idA pivot_set_id, eqtype_jobs. job_idA pivot_job_id, eqtype_jobs, created_ats a pivot_created_ats, eqtype_jobs. updated_atA pivot_updated_at, eqtype_jobs. id, Jak pivot_idz jobspołączenie wewnętrzne eqtype_jobswłączone jobs. id= eqtype_jobs. job_idgdzie eqtype_jobs. set_id= 56 zamówienia według pivot_created_atdesc limit 20 offset 0) (Widok: /home/said/www/factory/resources/views/set/show.blade.php)

Powyższy komunikat o błędzie zwraca pełne zapytanie SQL z błędem

SQL: select  jobs.*, eqtype_jobs.set_id as pivot_set_id,  eqtype_jobs.job_id as pivot_job_id, eqtype_jobs.created_ats as pivot_created_ats, eqtype_jobs.updated_at as  pivot_updated_at, eqtype_jobs.id as pivot_id from jobs inner join eqtype_jobs on jobs.id = eqtype_jobs.job_id where  eqtype_jobs.set_id = 56 order by pivot_created_at desc limit 20 offset 0

Teraz po prostu usuń dodatkowe elementy sz Created_at i przetestuj ten SQL, jak chcesz, w dowolnym edytorze SQL, takim jak edytor SQL phpMyAdmin!

Ogłoszenie:

Rozwiązanie zostało przetestowane z Laravelem 5.4 .

SaidbakR
źródło
2
Jak dotąd najlepsza odpowiedź! Tak prosty! :)
Picard
To nie wyświetli zapytania z powiązaniami, tzn. Powiązania będą wyglądały jak::id
Shantha Kumara,
@ShanthaKumara Rzeczywiście, nie wiem, jakiej wersji lub konfiguracji Laravela użyłeś. Jednak każdy fragment lub kod w mojej odpowiedzi został skopiowany i wklejony z rzeczywistego kodu wyjściowego projektu Laravel 5.4.
SaidbakR
6

Aby zobaczyć wykonanie zapytania Laravel, użyj dziennika zapytań laravel

DB::enableQueryLog();

$queries = DB::getQueryLog();
Jasim Juwel
źródło
6

Od wersji Laravel 5.8.15 narzędzie do tworzenia zapytań ma teraz metody ddi dumpmetody, dzięki którym można to zrobić

DB::table('data')->where('a', 1)->dump();
Greg
źródło
Dzięki. dd działa naprawdę dobrze. DB :: table ('data') -> where ('a', 1) -> dd ();
Waqas
Lepsze niż inne wymienione odpowiedzi.
Hamees A. Khan
5

To jest funkcja, którą umieściłem w mojej klasie modelu podstawowego. Wystarczy przekazać do niego obiekt konstruktora zapytań, a łańcuch SQL zostanie zwrócony.

function getSQL($builder) {
  $sql = $builder->toSql();
  foreach ( $builder->getBindings() as $binding ) {
    $value = is_numeric($binding) ? $binding : "'".$binding."'";
    $sql = preg_replace('/\?/', $value, $sql, 1);
  }
  return $sql;
}
BoogieBug
źródło
4

Dla laravel 5.5.X

Jeśli chcesz otrzymywać każde zapytanie SQL wykonane przez aplikację, możesz użyć metody Listen. Ta metoda jest przydatna do rejestrowania zapytań lub debugowania. Możesz zarejestrować swój detektor zapytań u usługodawcy:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            // $query->sql
            // $query->bindings
            // $query->time
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Źródło

scre_www
źródło
4

Dodaj tę funkcję do aplikacji i po prostu zadzwoń.

function getQuery($sql){
        $query = str_replace(array('?'), array('\'%s\''), $sql->toSql());
        $query = vsprintf($query, $sql->getBindings());     
        return $query;
}

Wyjście : „wybierz *, userskąd lang=„ en ”i status=„ 1 ”porządek według updated_atograniczenia desc 25 przesunięcie 0”

Dharmik
źródło
3

Możesz użyć tego pakietu, aby uzyskać wszystkie zapytania, które są wykonywane podczas ładowania strony

https://github.com/barryvdh/laravel-debugbar
Lakhwinder Singh
źródło
Ten pakiet jest dobry, gdy nie masz błędów zapytań. Jeśli masz błąd SQL, nic nie pokaże
lewis4u
3

Wydrukuj ostatnie zapytanie

DB::enableQueryLog();

$query        = DB::getQueryLog();
$lastQuery    = end($query);
print_r($lastQuery);
Sohomdeep Paul
źródło
2

Jeśli nie używasz Laravela, ale używasz pakietu Eloquent:

use \Illuminate\Database\Capsule\Manager as Capsule;
use \Illuminate\Events\Dispatcher;
use \Illuminate\Container\Container;

$capsule = new Capsule;

$capsule->addConnection([
    // connection details
]);
// Set the event dispatcher used by Eloquent models... (optional)
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Make this Capsule instance available globally via static methods... (optional)
$capsule->setAsGlobal();

// Setup the Eloquent ORM...(optional unless you've used setEventDispatcher())
$capsule->bootEloquent();

// Listen for Query Events for Debug
$events = new Dispatcher;
$events->listen('illuminate.query', function($query, $bindings, $time, $name)
{
    // Format binding data for sql insertion
    foreach ($bindings as $i => $binding) {
        if ($binding instanceof \DateTime) {
            $bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
        } else if (is_string($binding)) {
            $bindings[$i] = "'$binding'";`enter code here`
        }
    }

    // Insert bindings into query
    $query = str_replace(array('%', '?'), array('%%', '%s'), $query);
    $query = vsprintf($query, $bindings);

    // Debug SQL queries
    echo 'SQL: [' . $query . ']';
});

$capsule->setEventDispatcher($events);
Salman Ahmed
źródło
2

możesz użyć mechanizmu zegarowego

Clockwork to rozszerzenie Chrome do programowania PHP, rozszerzające Narzędzia programistyczne o nowy panel zapewniający wszelkiego rodzaju informacje przydatne do debugowania i profilowania aplikacji PHP, w tym informacje o żądaniach, nagłówkach, danych do pobierania i wysyłania, pliki cookie, dane sesji, zapytania do bazy danych, trasy, wizualizacja środowiska wykonawczego aplikacji i inne.

ale działa również w Firefoksie

wdog
źródło
2

Stworzyłem kilka prostych funkcji, aby uzyskać SQL i powiązania z niektórych zapytań.

/**
 * getSql
 *
 * Usage:
 * getSql( DB::table("users") )
 * 
 * Get the current SQL and bindings
 * 
 * @param  mixed  $query  Relation / Eloquent Builder / Query Builder
 * @return array          Array with sql and bindings or else false
 */
function getSql($query)
{
    if( $query instanceof Illuminate\Database\Eloquent\Relations\Relation )
    {
        $query = $query->getBaseQuery();
    }

    if( $query instanceof Illuminate\Database\Eloquent\Builder )
    {
        $query = $query->getQuery();
    }

    if( $query instanceof Illuminate\Database\Query\Builder )
    {
        return [ 'query' => $query->toSql(), 'bindings' => $query->getBindings() ];
    }

    return false;
}

/**
 * logQuery
 *
 * Get the SQL from a query in a closure
 *
 * Usage:
 * logQueries(function() {
 *     return User::first()->applications;
 * });
 * 
 * @param  closure $callback              function to call some queries in
 * @return Illuminate\Support\Collection  Collection of queries
 */
function logQueries(closure $callback) 
{
    // check if query logging is enabled
    $logging = DB::logging();

    // Get number of queries
    $numberOfQueries = count(DB::getQueryLog());

    // if logging not enabled, temporarily enable it
    if( !$logging ) DB::enableQueryLog();

    $query = $callback();

    $lastQuery = getSql($query);

    // Get querylog
    $queries = new Illuminate\Support\Collection( DB::getQueryLog() );

    // calculate the number of queries done in callback
    $queryCount = $queries->count() - $numberOfQueries;

    // Get last queries
    $lastQueries = $queries->take(-$queryCount);

    // disable query logging
    if( !$logging ) DB::disableQueryLog();

    // if callback returns a builder object, return the sql and bindings of it
    if( $lastQuery )
    {
        $lastQueries->push($lastQuery);
    }

    return $lastQueries;
}

Stosowanie:

getSql( DB::table('users') );
// returns 
// [
//     "sql" => "select * from `users`",
//     "bindings" => [],
// ]

getSql( $project->rooms() );
// returns
// [
//     "sql" => "select * from `rooms` where `rooms`.`project_id` = ? and `rooms`.`project_id` is not null",
//     "bindings" => [ 7 ],
// ]
blablabla
źródło
2

Mimo że uwielbiam ten framework, nienawidzę, gdy działa jak bzdury.

DB::enableQueryLog()jest całkowicie bezużyteczne. DB::listenjest równie bezużyteczne. Kiedy powiedziałem $query->count(), pokazał część zapytania , ale jeśli to zrobię $query->get(), nie ma nic do powiedzenia.

Jedynym rozwiązaniem, które wydaje się działać konsekwentnie, jest celowe wstawienie składni lub innego błędu w parametrach ORM, takich jak nieistniejąca nazwa kolumny / tabeli, uruchomienie kodu w wierszu poleceń w trybie debugowania, a to wypluje błąd SQL wreszcie pełne zapytanie. W przeciwnym razie mam nadzieję, że błąd pojawi się w pliku dziennika, jeśli został uruchomiony z serwera WWW.

Spencer Williams
źródło
Dziennik zapytań działa przynajmniej dla mnie dobrze. Powinieneś mieć inne błędy w swojej aplikacji
user1415066
1

Jeśli używasz majstrowania i chcesz zarejestrować utworzone zapytanie SQL, możesz to zrobić

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.5  cli) by Justin Hileman
>>> DB::listen(function ($query) { dump($query->sql); dump($query->bindings); dump($query->time); });
=> null
>>> App\User::find(1)
"select * from `users` where `users`.`id` = ? limit 1"
array:1 [
  0 => 1
]
6.99
=> App\User {#3131
     id: 1,
     name: "admin",
     email: "[email protected]",
     created_at: "2019-01-11 19:06:23",
     updated_at: "2019-01-11 19:06:23",
   }
>>>
Prafulla Kumar Sahu
źródło
1

Spróbuj tego:

$results = DB::table('users')->toSql();
dd($results);

Uwaga: get () zostało zastąpione przez toSql (), aby wyświetlić surowe zapytanie SQL.

Nikhil Gyan
źródło
1

Mój sposób na zrobienie tego, oparty na widoku dziennika, wymaga jedynie modyfikacji pliku app/Providers/AppServiceProvider.php:

  1. Dodaj ten kod do app/Providers/AppServiceProvider.php
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    //
    DB::listen(function ($query) {
        $querySql = str_replace(['?'], ['\'%s\''], $query->sql);
        $queryRawSql = vsprintf($querySql, $query->bindings);
        Log::debug('[SQL EXEC]', [
                "raw sql"  => $queryRawSql,
                "time" => $query->time,
            ]
        );
    });
}
  1. Mój kod obsługi SQL:
$users = DB::table('users')
    ->select(DB::raw('count(*) as user_count, username '))
    ->where('uid', '>=', 10)
    ->limit(100)
    ->groupBy('username')
    ->get()
;
dd($users);
  1. Zobacz dziennik storage/logs/laravel-2019-10-27.log:
[2019-10-27 17:39:17] local.DEBUG: [SQL EXEC] {"raw sql":"select count(*) as user_count, username  from `users` where `uid` >= '10' group by `username` limit 100","time":304.21} 
Lupguo
źródło