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?


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.)


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.


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


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

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

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 ...


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

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


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
  ]
]

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

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 :)


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

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


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

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 .


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

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

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


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


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”


3

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

https://github.com/barryvdh/laravel-debugbar

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

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

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


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 ],
// ]

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.


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: "admin@example.com",
     created_at: "2019-01-11 19:06:23",
     updated_at: "2019-01-11 19:06:23",
   }
>>>

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.


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} 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.