¿Cómo consigo que el generador de consultas genere su consulta SQL sin formato como una cadena?
545
Dado el siguiente código:
DB::table('users')->get();
Quiero obtener la cadena de consulta SQL sin procesar que generará el generador de consultas de base de datos anterior. En este ejemplo, sería SELECT * FROM users.
Incluso podría ser mejor LogLog::debug(DB::getQueryLog())
enviarlo
35
Es posible que deba habilitar esto ya que ahora está desactivado de manera predeterminada. Puede usar este comando para activarlo temporalmente:DB::enableQueryLog();
Joshua Fricke
55
Intenté tu respuesta. Lo que intenté es DB::enableQueryLog(); dd(DB::getQueryLog());Pero regresa solo []...
Soy la persona más estúpida
66
Si tiene varias bases de datos, es posible que deba hacerloDB::connection('database')->getQueryLog()
Damien Ó Ceallaigh el
745
Use el toSql()método en una QueryBuilderinstancia.
DB::table('users')->toSql() volvería:
seleccione * de `usuarios`
Esto es más fácil que conectar un detector de eventos, y también le permite verificar cómo se verá la consulta en cualquier momento mientras la construye.
Creo que esta es la forma más fácil cuando se usa Eloquent fuera de Laravel
Gab
8
@Stormsson Eso no es posible porque PHP nunca tiene la consulta con los enlaces reemplazados por sus valores. Para obtener las consultas en su totalidad, debe registrarlas desde MySQL. Hay más información aquí: stackoverflow.com/questions/1786322/…
Matthew
40
@Stormsson puedes usar el getBindingsmétodo. Esto devolverá los enlaces para que estén vinculados a la instrucción SQL.
danronmoon 01 de
2
Muy útil para depurar consultas complicadas que Eloquent se niega a ejecutar, ya que no se muestran en el registro de consultas.
BobChao87
34
Para obtener consultas con enlaces$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
Ennio Sousa
88
DB::QueryLog()solo funciona después de ejecutar la consulta $builder->get(). si desea obtener la consulta antes de ejecutarla, puede usar el $builder->toSql()método este es el ejemplo de cómo obtener el sql y vincularlo:
Esta es, de lejos, la mejor respuesta, simple y directa al grano. Gracias :)
Sobakus
18
Como una $query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
frase
Esto debería incluirse en el marco como una función nativa ... gracias
Tomáš Mleziva
Tenga en cuenta que esto no funcionará si su consulta ya tiene signos de porcentaje, como para una LIKEconsulta o al formatear fechas. Tendrás que escapar de esos primero con signos de doble porcentaje.
The Unknown Dev
¿Hay problemas de seguridad al hacer esto? ¿Las fijaciones vienen desinfectadas $builder->getBindings()?
solidau
56
Puede escuchar el evento 'illuminate.query'. Antes de la consulta, agregue el siguiente detector de eventos:
Recibo una llamada al método indefinido Illuminate \ Database \ Query \ Builder :: listen () en Laravel 4
Miguel Stevens
2
Gracias esto es genial. Es bueno tener en cuenta que dd es una función que produce un volcado de la variable dada y finaliza la ejecución de la secuencia de comandos y también que para importar Evento, incluiruse Illuminate\Support\Facades\Event;
radtek
1
@radtek: En lugar de use Illuminate\Support\Facades\Event;hacerlo, simplemente puedes hacerlo use Event;ya que es una fachada .
TachyonVortex
50
Si está intentando obtener el Log usando Illuminate sin usar Laravel:
Las versiones actualizadas parecen tener el registro de consultas deshabilitado de forma predeterminada (lo anterior devuelve una matriz vacía). Para volver a encenderlo, al inicializar el Administrador de cápsulas, tome una instancia de la conexión y llame al enableQueryLogmétodo
$capsule::connection()->enableQueryLog();
EDITAR DE NUEVO
Teniendo en cuenta la pregunta real, en realidad podría hacer lo siguiente para convertir la consulta única actual en lugar de todas las consultas anteriores:
obtengo este tipo de devolución de la consulta "name = [{" name ":" rifat "}]" ¿qué necesito hacer para obtener "name = rifat" solamente?
incorporeal
Imprimiría tus enlaces, parece que estás pasando una matriz en lugar de una cadena
Luke Snowden
Este es un comienzo útil, pero parece descuidar agregar comillas simples alrededor de valores parametrizados, como cuando paso una cadena como 'US/Eastern'.
Ryan
1
@ Ryan, esto es cierto, por eso dije quick function. Creo que el código subyacente utilizará los métodos prepare ( php.net/manual/en/mysqli.prepare.php ), razón por la cual solo ?se requiere. Puede php.net/manual/en/function.is-numeric.php para determinar si encapsular o no la entrada entre comillas simples.
Luke Snowden
1
@LukeSnowden ¡Tu respuesta es genial! Finalmente me tomé el tiempo para probar su nueva versión (que edité anteriormente para incluir su is_numericidea), ¡y funciona! Me encanta esto. Gracias.
Ryan
36
Hay un método en elocuente para obtener una cadena de consulta.
toSql ()
en nuestro caso,
DB::table('users')->toSql();
regreso
select*from users
es la solución exacta que devuelve la cadena de consulta SQL ... Espero que esto sea útil ...
Respuesta mejorada para incluir todas las observaciones hechas en los comentarios. Muchas gracias.
Yevgeniy Afanasyev
13
Primero, deberá habilitar el registro de consultas llamando a:
DB::enableQueryLog();
Después de las consultas que utilizan la fachada DB, puede escribir:
dd(DB::getQueryLog());
la salida tendrá gusto abajo:
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]]
hola, he usado $ result = DB :: select ('select * from sqrt_user_modules donde user_id =: id', ['id' => $ user]); DB :: enableQueryLog (); pero no obtuvo ninguna salida dd (DB :: getQueryLog ());
Anoop PS
¿necesitamos incluir alguna biblioteca?
Anoop PS
1
Paso 1: DB :: enableQueryLog (); paso 2: $ result = DB :: select ('select * from sqrt_user_modules donde user_id =: id', ['id' => $ user]); paso 3: dd (DB :: getQueryLog ());
Ravi Mane
12
Esta es la mejor solución que puedo sugerir a cualquiera para depurar la última consulta o consulta final elocuente, aunque esto también se ha discutido:
Nota: de Laravel 5.1 a 5.3, dado que Eloquent Builder no hace uso del Macroablerasgo, no puede agregar toRawSqlun alias al Eloquent Builder sobre la marcha. Siga el siguiente ejemplo para lograr lo mismo.
Por ejemplo, Eloquent Builder ( Laravel 5.1 - 5.3 )
Lo de escuchar es útil, declararlo antes de ejecutar la consulta y deshacerse de los enlaces sql & dentro del método. Imperfecto pero funciona más rápido / más fácil que otras respuestas.
Andrew
7
La forma más fácil es cometer un error deliberado . Por ejemplo, quiero ver la consulta SQL completa de la siguiente relación:
Entonces, el depurador devolverá el siguiente error:
(4/4) ErrorException SQLSTATE [42S22]: La columna no encontrado: 1054 Desconocido columna 'eqtype_jobs.created_ats' en 'lista de campos' (SQL: select
jobs*,. eqtype_jobs. set_idComo pivot_set_id,
eqtype_jobs. job_idComo pivot_job_id, eqtype_jobs. created_ats
Como pivot_created_ats, eqtype_jobs. updated_atComo
pivot_updated_at, eqtype_jobs. idComo pivot_idde jobsunión interna eqtype_jobsen jobs. id= eqtype_jobs. job_idwhere
eqtype_jobs. set_id= 56 orden por pivot_created_atlímite límite 20 offset 0) (Ver: /home/said/www/factory/resources/views/set/show.blade.php)
El mensaje de error anterior devuelve la consulta SQL completa con el error
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
¡Ahora, simplemente elimine el extra sde created_at y pruebe este SQL como desee en cualquier editor de SQL como phpMyAdmin SQL editor!
¡Esta es la mejor respuesta con diferencia! ¡Tan sencillo! :)
Picard
Esto no mostrará la consulta con enlaces, es decir, los enlaces se mostrarán como:id
Shantha Kumara
@ShanthaKumara De hecho, no sé cuál es la versión o la configuración de Laravel que ha utilizado. Sin embargo, cada fragmento o código en mi respuesta fue copiado y pegado de la salida de código real del proyecto Laravel 5.4.
SaidbakR
6
Para ver la consulta ejecutada de Laravel, use el registro de consultas de laravel
Si desea recibir cada consulta SQL ejecutada por su aplicación, puede usar el método de escucha. Este método es útil para registrar consultas o depurar. Puede registrar su escucha de consultas en un proveedor de servicios:
<?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 es una extensión de Chrome para el desarrollo de PHP, que extiende las Herramientas para desarrolladores con un nuevo panel que proporciona todo tipo de información útil para depurar y perfilar sus aplicaciones PHP, incluida información sobre solicitudes, encabezados, obtener y publicar datos, cookies, datos de sesión, consultas de bases de datos, rutas, visualización del tiempo de ejecución de la aplicación y más.
He creado algunas funciones simples para obtener el SQL y los enlaces de algunas consultas.
/**
* 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;}
Uso:
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 ],// ]
Por mucho que ame este marco, odio cuando actúa como una mierda.
DB::enableQueryLog()Es totalmente inútil. DB::listenEs igualmente inútil. Mostró parte de la consulta cuando dije $query->count(), pero si lo hago $query->get(), no tiene nada que decir.
La única solución que parece funcionar consistentemente es poner intencionalmente alguna sintaxis u otro error en los parámetros ORM, como un nombre de columna / tabla inexistente, ejecutar su código en la línea de comando mientras está en modo de depuración, y escupirá el error SQL con la maldita consulta completa finalmente. De lo contrario, es de esperar que el error aparezca en el archivo de registro si se ejecuta desde el servidor web.
$users = DB::table('users')->select(DB::raw('count(*) as user_count, username '))->where('uid','>=',10)->limit(100)->groupBy('username')->get();
dd($users);
Ver registro 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();
Respuestas:
Para enviar a la pantalla las últimas consultas ejecutadas, puede usar esto:
Creo que las consultas más recientes estarán en la parte inferior de la matriz.
Tendrás algo así:
(Gracias al comentario de Joshua a continuación).
fuente
Log
Log::debug(DB::getQueryLog())
DB::enableQueryLog();
DB::enableQueryLog(); dd(DB::getQueryLog());
Pero regresa solo[]
...DB::connection('database')->getQueryLog()
Use el
toSql()
método en unaQueryBuilder
instancia.DB::table('users')->toSql()
volvería:Esto es más fácil que conectar un detector de eventos, y también le permite verificar cómo se verá la consulta en cualquier momento mientras la construye.
fuente
getBindings
método. Esto devolverá los enlaces para que estén vinculados a la instrucción SQL.$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
DB::QueryLog()
solo funciona después de ejecutar la consulta$builder->get()
. si desea obtener la consulta antes de ejecutarla, puede usar el$builder->toSql()
método este es el ejemplo de cómo obtener el sql y vincularlo:O simplemente cometa su error de consulta como llamar a una tabla o columna inexistente, verá la consulta generada en la excepción XD
fuente
$query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
LIKE
consulta o al formatear fechas. Tendrás que escapar de esos primero con signos de doble porcentaje.$builder->getBindings()
?Puede escuchar el evento 'illuminate.query'. Antes de la consulta, agregue el siguiente detector de eventos:
Esto imprimirá algo como:
fuente
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Event;
hacerlo, simplemente puedes hacerlouse Event;
ya que es una fachada .Si está intentando obtener el Log usando Illuminate sin usar Laravel:
También podría crear una función rápida como esta:
EDITAR
Las versiones actualizadas parecen tener el registro de consultas deshabilitado de forma predeterminada (lo anterior devuelve una matriz vacía). Para volver a encenderlo, al inicializar el Administrador de cápsulas, tome una instancia de la conexión y llame al
enableQueryLog
métodoEDITAR DE NUEVO
Teniendo en cuenta la pregunta real, en realidad podría hacer lo siguiente para convertir la consulta única actual en lugar de todas las consultas anteriores:
fuente
'US/Eastern'
.quick function
. Creo que el código subyacente utilizará los métodos prepare ( php.net/manual/en/mysqli.prepare.php ), razón por la cual solo?
se requiere. Puede php.net/manual/en/function.is-numeric.php para determinar si encapsular o no la entrada entre comillas simples.is_numeric
idea), ¡y funciona! Me encanta esto. Gracias.Hay un método en elocuente para obtener una cadena de consulta.
toSql ()
en nuestro caso,
regreso
es la solución exacta que devuelve la cadena de consulta SQL ... Espero que esto sea útil ...
fuente
->where('foo', '=', 'bar')
bar no se mostrará en el sqlfuente
->toSql()
como lo haría si hubiera más argumentos después del modelo. Por ejemploUser::where('id', 1)->toSql()
Si usa laravel 5.1 y MySQL puede usar esta función hecha por mí:
Como parámetro de entrada puede usar cualquiera de estos
fuente
Primero, deberá habilitar el registro de consultas llamando a:
Después de las consultas que utilizan la fachada DB, puede escribir:
la salida tendrá gusto abajo:
fuente
Esta es la mejor solución que puedo sugerir a cualquiera para depurar la última consulta o consulta final elocuente, aunque esto también se ha discutido:
fuente
Primera forma:
Simplemente puedes hacer lo siguiente usando el
toSql()
método,Si no funciona, puede configurarlo desde la documentación de laravel .
Segunda forma:
Otra forma de hacerlo es
DB::getQueryLog()
pero si devuelve una matriz vacía, por defecto está deshabilitada, visite este ,
solo habilitar con
DB::enableQueryLog()
y funcionará :)Para más información, visita Github Issue para saber más al respecto.
Espero eso ayude :)
fuente
Un reemplazo 'macroable' para obtener la consulta SQL con los enlaces.
Agregue debajo la función macro en el método.
AppServiceProvider
boot()
Agregue un alias para Eloquent Builder. ( Laravel 5.4+ )
Luego depure como de costumbre. ( Laravel 5.4+ )
Por ejemplo, generador de consultas
Ej. Eloquent Builder
Por ejemplo, Eloquent Builder ( Laravel 5.1 - 5.3 )
fuente
usa el paquete debugbar
fuente
De laravel
5.2
y en adelante. puede usarDB::listen
para obtener consultas ejecutadas.O si desea depurar una sola
Builder
instancia, puede usar eltoSql
método.fuente
La forma más fácil es cometer un error deliberado . Por ejemplo, quiero ver la consulta SQL completa de la siguiente relación:
Solo para hacer que una columna no se encuentre, aquí elijo
created_at
y la cambiécreated_ats
agregando el finals
para que sea:Entonces, el depurador devolverá el siguiente error:
El mensaje de error anterior devuelve la consulta SQL completa con el error
¡Ahora, simplemente elimine el extra
s
de created_at y pruebe este SQL como desee en cualquier editor de SQL como phpMyAdmin SQL editor!fuente
:id
Para ver la consulta ejecutada de Laravel, use el registro de consultas de laravel
fuente
A partir de Laravel 5.8.15, el generador de consultas ahora tiene
dd
ydump
métodos para que pueda hacerfuente
Esta es la función que puse en mi clase de modelo base. Simplemente pase el objeto generador de consultas y se devolverá la cadena SQL.
fuente
En mi opinión, este será el mejor enfoque como principiante:
Esto también se representa aquí. https://stackoverflow.com/a/59207557/9573341
fuente
Para laravel 5.5.X
Si desea recibir cada consulta SQL ejecutada por su aplicación, puede usar el método de escucha. Este método es útil para registrar consultas o depurar. Puede registrar su escucha de consultas en un proveedor de servicios:
Fuente
fuente
Agregue esta función a su aplicación y simplemente llame.
Salida : "seleccionar * desde
user
dondelang
= 'en' ystatus
= '1' ordenar porupdated_at
límite límite 25 desplazamiento 0"fuente
Puede usar este paquete para obtener todas las consultas que se ejecutan cuando carga su página
fuente
Imprimir última consulta
fuente
Si no está usando Laravel pero está usando el paquete Eloquent, entonces:
fuente
puedes usar un reloj
pero funciona también en firefox
fuente
He creado algunas funciones simples para obtener el SQL y los enlaces de algunas consultas.
Uso:
fuente
Por mucho que ame este marco, odio cuando actúa como una mierda.
DB::enableQueryLog()
Es totalmente inútil.DB::listen
Es igualmente inútil. Mostró parte de la consulta cuando dije$query->count()
, pero si lo hago$query->get()
, no tiene nada que decir.La única solución que parece funcionar consistentemente es poner intencionalmente alguna sintaxis u otro error en los parámetros ORM, como un nombre de columna / tabla inexistente, ejecutar su código en la línea de comando mientras está en modo de depuración, y escupirá el error SQL con la maldita consulta completa finalmente. De lo contrario, es de esperar que el error aparezca en el archivo de registro si se ejecuta desde el servidor web.
fuente
Si está utilizando tinker y desea registrar la consulta SQL formada, puede hacer
fuente
Prueba esto:
Nota: get () ha sido reemplazado por toSql () para mostrar la consulta SQL sin procesar.
fuente
Mi forma de hacerlo, basada en la vista de registro, solo necesita modificar el archivo
app/Providers/AppServiceProvider.php
:app/Providers/AppServiceProvider.php
storage/logs/laravel-2019-10-27.log
:fuente