Jak sprawić, by konstruktor zapytań wypuścił swoje surowe zapytanie SQL jako ciąg znaków?
Podano następujący kod:
DB::table('users')->get();
Chcę uzyskać surowy ciąg zapytania SQL, który wygeneruje powyższy konstruktor zapytań, więc w tym przykładzie będzie to SELECT * FROM users
.
23 answers
Do wyświetlenia na ekranie ostatnich zapytań możesz użyć tego
dd(DB::getQueryLog());
Wierzę, że ostatnie 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"
}
}
Zgodnie z komentarzem Joshuy poniżej, to jest teraz domyślnie wyłączone. Aby użyć, musisz włączyć go ręcznie za pomocą:
DB::enableQueryLog();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:03
Użyj metody toSql()
Na wystąpieniu QueryBuilder
.
DB::table('users')->toSql()
zwraca:
Select * from 'users'
Jest to łatwiejsze niż podłączenie słuchacza zdarzeń, a także pozwala sprawdzić, jak faktycznie będzie wyglądało zapytanie w dowolnym momencie podczas jego budowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-03 03:57:27
Możesz posłuchać ' illuminate.zapytanie " event. 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();
To wydrukuje coś w stylu:
array(4) {
[0]=>
string(21) "select * from "users""
[1]=>
array(0) {
}
[2]=>
string(4) "0.94"
[3]=>
string(6) "sqlite"
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-14 16:14:58
Jeśli próbujesz uzyskać Log za pomocą Illuminate bez użycia Laravela:
\Illuminate\Database\Capsule\Manager::getQueryLog();
Można też wstawić taką szybką funkcję:
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;
}
EDIT
Zaktualizowane wersje wydają się mieć domyślnie wyłączone rejestrowanie zapytań (powyższe zwraca pustą tablicę). Aby włączyć ponownie, podczas inicjalizacji Menedżera kapsułek, chwyć instancję połączenia i wywołaj metodę enableQueryLog
$capsule::connection()->enableQueryLog();
EDIT AGAIN
Biorąc rzeczywiste pytanie do aby przekonwertować bieżące pojedyncze zapytanie zamiast wszystkich poprzednich, możesz wykonać następujące czynności:
$sql = $query->toSql();
$bindings = $query->getBindings();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 17:10:34
DB::QueryLog()
działa tylko po wykonaniu zapytania $builder->get()
. jeśli chcesz uzyskać zapytanie przed jego wykonaniem, możesz użyć metody $builder->toSql()
. 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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 11:59:53
Istnieje metoda w eloquent do uzyskania ciągu zapytania.
ToSql()
W naszym przypadku,
DB::table('users')->toSql();
Return
select * from users
Jest dokładnym rozwiązaniem, które zwraca ciąg zapytania SQL..Mam nadzieję, że to pomoże...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 11:05:41
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 08:38:15
Jeśli używasz laravel 5.1 i MySQL możesz użyć tej funkcji wykonanej przeze mnie:
/*
* 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 tych
Illuminate\Database\Eloquent\Builder
Illuminate\Database\Eloquent\Relations\HasMany
Illuminate\Database\Query\Builder
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 23:45:31
Pierwsza droga:
Po prostu możesz zrobić następujące rzeczy za pomocą toSql()
metoda,
$query = DB::table('users')->get();
echo $query->toSql();
Jeśli to nie działa, możesz skonfigurować to z dokumentacji Laravela.
Druga droga:
Innym sposobem jest
DB::getQueryLog()
Ale jeśli zwraca pustą tablicę to domyślnie jest wyłączona odwiedź to ,
Wystarczy włączyć z DB::enableQueryLog()
i będzie działać:)
Aby uzyskać więcej informacji odwiedź Github Issue aby dowiedzieć się więcej na ten temat.
Mam nadzieję, że pomoże:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-25 05:45:00
Od laravel 5.2
i dalej. możesz użyć DB::listen
, aby uzyskać wykonywane zapytania.
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
Lub jeśli chcesz debugować pojedynczą instancję Builder
, możesz użyć metody toSql
.
DB::table('posts')->toSql();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 17:01:59
To jest funkcja, którą umieściłem w mojej klasie modeli bazowych. Po prostu przekaż obiekt Query builder do niego, 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-28 08:59:41
Dla laravel 5.5.X
Jeśli chcesz otrzymywać każde zapytanie SQL wykonane przez Twoją aplikację, możesz użyć metody listen. Ta metoda jest przydatna do rejestrowania zapytań lub debugowania. Możesz zarejestrować swoje zapytanie w 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()
{
//
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 09:53:20
Aby zobaczyć wykonane zapytanie Laravel użyj dziennika zapytań laravel
DB::enableQueryLog();
$queries = DB::getQueryLog();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 05:37:49
Najpierw musisz włączyć dziennik zapytań, wywołując:
DB::enableQueryLog();
Po zapytaniach wykorzystujących fasadę DB można napisać:
dd(DB::getQueryLog());
Wyjście będzie takie jak 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
]
]
Blockquote
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-31 04:29:41
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-18 08:09:28
Możesz użyć tego pakietu, aby uzyskać wszystkie zapytania, które są wykonywane podczas ładowania strony
https://github.com/barryvdh/laravel-debugbar
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 14:01:26
Jeśli nie używasz Laravel, ale używasz Eloquent package to:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 09:29:02
Możesz użyć clockwork
Clockwork to rozszerzenie Chrome do programowania PHP, rozszerzające narzędzia programistyczne o nowy panel dostarczający wszelkiego rodzaju informacje przydatne do debugowania i profilowania aplikacji PHP, w tym informacje o żądaniach, nagłówkach, danych get I post, plikach Cookie, danych sesji, zapytaniach do bazy danych, trasach, wizualizacji czasu pracy aplikacji i innych.
Ale działa również w Firefoksie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 16:39:03
Stworzyłem kilka prostych funkcji, aby uzyskać sql i wią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;
}
Użycie:
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 ],
// ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 10:55:18
Najprostszym sposobem jest popełnienie celowego błędu . 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');
}
Po prostu aby kolumna nie została znaleziona, tutaj wybieram created_at
i zmieniłem ją na created_ats
przez dodanie s
na:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_ats','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
Więc debuger zwróci następujący błąd:
(4/4) ErrorException SQLSTATE [42S22]: Column not found: 1054 Unknown kolumna " eqtype_jobs.created_ats ' in 'field list' (SQL: wybierz
jobs
.*,eqtype_jobs
.set_id
jakopivot_set_id
,eqtype_jobs
.job_id
jakopivot_job_id
,eqtype_jobs
.created_ats
jakopivot_created_ats
,eqtype_jobs
.updated_at
jakopivot_updated_at
,eqtype_jobs
.id
aspivot_id
fromjobs
inner dołącz doeqtype_jobs
najobs
.id
=eqtype_jobs
.job_id
gdzieeqtype_jobs
.set_id
= 56 order bypivot_created_at
DESC 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 s
z created_at i przetestuj ten SQL, jak chcesz w dowolnym edytorze SQL, takim jak phpMyAdmin edytor SQL!
Notice:
Roztwór został przetestowany za pomocą Laravel 5.4.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 19:34:12
Oto rozwiązanie, którego używam:
DB::listen(function ($sql, $bindings, $time) {
$bound = preg_replace_callback("/\?/", function($matches) use ($bindings) {
static $localBindings;
if (!isset($localBindings)) {
$localBindings = $bindings;
}
$val = array_shift($localBindings);
switch (gettype($val)) {
case "boolean":
$val = ($val === TRUE) ? 1 : 0; // mysql doesn't support BOOL data types, ints are widely used
// $val = ($val === TRUE) ? "'t'" : "'f'"; // todo: use this line instead of the above for postgres and others
break;
case "NULL":
$val = "NULL";
break;
case "string":
case "object":
$val = "'". addslashes($val). "'"; // correct escaping would depend on the RDBMS
break;
}
return $val;
}, $sql);
array_map(function($x) {
(new \Illuminate\Support\Debug\Dumper)->dump($x);
}, [$sql, $bindings, $bound]);
});
Proszę przeczytać komentarze w kodzie. Wiem, że nie jest idealny, ale dla mojego codziennego debugowania jest OK. Próbuje zbudować związane zapytanie z większą lub mniejszą niezawodnością. Jednak nie ufaj mu całkowicie, silniki bazodanowe inaczej uciekają od wartości, których ta krótka funkcja nie implementuje. Więc weź wynik ostrożnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-05 07:55:43
Drukuj Ostatnie zapytanie
DB::enableQueryLog();
$query = DB::getQueryLog();
$lastQuery = end($query);
print_r($lastQuery);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 07:18:12
Tak bardzo jak kocham ten framework, nienawidzę kiedy zachowuje się jak gówno.
DB::enableQueryLog()
jest całkowicie bezużyteczny. DB::listen
jest równie bezużyteczny. Pokazała część zapytania, kiedy powiedziałem $query->count()
, ale jeśli zrobię $query->get()
, nie ma nic do powiedzenia.
Jedynym rozwiązaniem, które wydaje się działać konsekwentnie, jest celowe umieszczenie niektórych błędów składni lub innych w parametrach ORM, takich jak nieistniejąca nazwa kolumny/tabeli, uruchomienie kodu w linii poleceń podczas trybu debugowania, a to wypluje błąd SQL z w końcu pełne cholerne zapytanie. W przeciwnym razie, miejmy nadzieję, że błąd pojawi się w pliku dziennika, jeśli został uruchomiony z serwera www.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-14 22:17:26