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.
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.
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:
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ń:
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:
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ń:
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'.
@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 ...
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]]
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:
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.
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:
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 .
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
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.
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
namespaceApp\Providers;useIlluminate\Support\Facades\DB;useIlluminate\Support\ServiceProvider;classAppServiceProviderextendsServiceProvider{/**
* Bootstrap any application services.
*
* @return void
*/publicfunction boot(){
DB::listen(function($query){// $query->sql// $query->bindings// $query->time});}/**
* Register the service provider.
*
* @return void
*/publicfunctionregister(){//}}
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.
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 instanceofIlluminate\Database\Eloquent\Relations\Relation ){
$query = $query->getBaseQuery();}if( $query instanceofIlluminate\Database\Eloquent\Builder ){
$query = $query->getQuery();}if( $query instanceofIlluminate\Database\Query\Builder ){return['query'=> $query->toSql(),'bindings'=> $query->getBindings()];}returnfalse;}/**
* 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 itif(!$logging ) DB::enableQueryLog();
$query = $callback();
$lastQuery = getSql($query);// Get querylog
$queries =newIlluminate\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 loggingif(!$logging ) DB::disableQueryLog();// if callback returns a builder object, return the sql and bindings of itif( $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 ],// ]
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.
$users = DB::table('users')->select(DB::raw('count(*) as user_count, username '))->where('uid','>=',10)->limit(100)->groupBy('username')->get();
dd($users);
Zobacz dziennik storage/logs/laravel-2019-10-27.log:
[2019-10-2717: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}
echo User::where('status', 1)->toSql();
Odpowiedzi:
Aby wyświetlić na ekranie ostatnie uruchomione zapytania, możesz użyć tego:
Wierzę, że najnowsze zapytania będą na dole tablicy.
Będziesz miał coś takiego:
(Dzięki komentarzowi Jozuego poniżej.)
źródło
Log
Log::debug(DB::getQueryLog())
DB::enableQueryLog();
DB::enableQueryLog(); dd(DB::getQueryLog());
ale powraca tylko[]
...DB::connection('database')->getQueryLog()
Użyj
toSql()
metody dlaQueryBuilder
instancji.DB::table('users')->toSql()
wróciłby: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.
źródło
getBindings
metody. Spowoduje to zwrócenie powiązań w celu ich powiązania z instrukcją SQL.$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
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:LUB po prostu zrób błąd zapytania, np. Wywołanie nieistniejącej tabeli lub kolumny, zobaczysz wygenerowane zapytanie w wyjątku XD
źródło
$query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
LIKE
zapytanie lub podczas formatowania dat. Najpierw musisz uciec przed tymi z podwójnymi znakami procentowymi.$builder->getBindings()
?Możesz odsłuchać wydarzenie „illuminate.query”. Przed zapytaniem dodaj następujący detektor zdarzeń:
Spowoduje to wydrukowanie czegoś takiego:
źródło
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Event;
możesz po prostu zrobić,use Event;
ponieważ jest to fasada .Jeśli próbujesz uzyskać Dziennik za pomocą Podświetlania bez Laravela, użyj:
Możesz także skorzystać z szybkiej funkcji, takiej jak:
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
enableQueryLog
metodę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ń:
źródło
'US/Eastern'
.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.is_numeric
pomysł) i działa! Uwielbiam to. Dziękuję Ci.Jest elokwentny sposób na uzyskanie ciągu zapytania.
toSql ()
w naszym przypadku,
powrót
jest dokładne rozwiązanie, które zwraca ciąg zapytania SQL .. Mam nadzieję, że to pomocne ...
źródło
->where('foo', '=', 'bar')
bar nie pokaże się w sqlźródło
->toSql()
tak jak w przypadku, gdy po modelu jest więcej argumentów. np.User::where('id', 1)->toSql()
Jeśli używasz laravel 5.1 i MySQL, możesz skorzystać z tej funkcji:
Jako parametr wejściowy możesz użyć jednego z nich
źródło
Najpierw musisz włączyć dziennik zapytań, wywołując:
po zapytaniach za pomocą fasady DB możesz napisać:
wynik polubi się poniżej:
źródło
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:
źródło
Pierwszy sposób:
Po prostu możesz wykonać następujące czynności przy użyciu
toSql()
metody,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 :)
źródło
„Macroable” wymiana dostać zapytanie SQL z wiązaniami.
Dodaj poniżej funkcję makra w metodzie.
AppServiceProvider
boot()
Dodaj alias do Eloquent Builder. ( Laravel 5.4+ )
Następnie debuguj jak zwykle. ( Laravel 5.4+ )
Np. Konstruktor zapytań
Np. Elokwentny konstruktor
Np. Eloquent Builder ( Laravel 5.1 - 5.3 )
źródło
użyj pakietu debugbar
źródło
Od Laravel
5.2
i dalej. możesz użyćDB::listen
do wykonania wykonanych zapytań.Lub jeśli chcesz debugować pojedyncze
Builder
wystąpienie, możesz użyćtoSql
metody.źródło
Najłatwiej jest popełnić celowy błąd . Na przykład chcę zobaczyć pełne zapytanie SQL następującej relacji:
Chcę tylko, aby kolumna nie została znaleziona, tutaj wybieram
created_at
i zmieniłem jącreated_ats
, dodając trailings
to:Debuger zwróci następujący błąd:
Powyższy komunikat o błędzie zwraca pełne zapytanie SQL z błędem
Teraz po prostu usuń dodatkowe elementy
s
z Created_at i przetestuj ten SQL, jak chcesz, w dowolnym edytorze SQL, takim jak edytor SQL phpMyAdmin!źródło
:id
Aby zobaczyć wykonanie zapytania Laravel, użyj dziennika zapytań laravel
źródło
Od wersji Laravel 5.8.15 narzędzie do tworzenia zapytań ma teraz metody
dd
idump
metody, dzięki którym można to zrobićźródło
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.
źródło
Moim zdaniem będzie to najlepsze podejście dla początkujących:
Jest to również przedstawione tutaj. https://stackoverflow.com/a/59207557/9573341
źródło
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:
Źródło
źródło
Dodaj tę funkcję do aplikacji i po prostu zadzwoń.
Wyjście : „wybierz *,
user
skądlang
=„ en ”istatus
=„ 1 ”porządek wedługupdated_at
ograniczenia desc 25 przesunięcie 0”źródło
Możesz użyć tego pakietu, aby uzyskać wszystkie zapytania, które są wykonywane podczas ładowania strony
źródło
Wydrukuj ostatnie zapytanie
źródło
Jeśli nie używasz Laravela, ale używasz pakietu Eloquent:
źródło
możesz użyć mechanizmu zegarowego
ale działa również w Firefoksie
źródło
Stworzyłem kilka prostych funkcji, aby uzyskać SQL i powiązania z niektórych zapytań.
Stosowanie:
źródło
Mimo że uwielbiam ten framework, nienawidzę, gdy działa jak bzdury.
DB::enableQueryLog()
jest całkowicie bezużyteczne.DB::listen
jest 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.
źródło
Jeśli używasz majstrowania i chcesz zarejestrować utworzone zapytanie SQL, możesz to zrobić
źródło
Spróbuj tego:
Uwaga: get () zostało zastąpione przez toSql (), aby wyświetlić surowe zapytanie SQL.
źródło
Mój sposób na zrobienie tego, oparty na widoku dziennika, wymaga jedynie modyfikacji pliku
app/Providers/AppServiceProvider.php
:app/Providers/AppServiceProvider.php
storage/logs/laravel-2019-10-27.log
:źródło