Comment puis-je obtenir le générateur de requêtes pour générer sa requête SQL brute sous forme de chaîne?

545

Étant donné le code suivant:

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

Je veux obtenir la chaîne de requête SQL brute que le générateur de requêtes de base de données ci-dessus va générer. Dans cet exemple, ce serait SELECT * FROM users.

Comment puis-je faire cela?

meiryo
la source
14
Laravel Eloquent ORM obtient une requête brute:echo User::where('status', 1)->toSql();
Muhammad Shahzad
J'utilise un paquet pour Laravel - Telescope, il enregistre toutes les requêtes et fait beaucoup plus de choses.
vinsa

Réponses:

662

Pour afficher à l'écran les dernières requêtes exécutées, vous pouvez utiliser ceci:

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

// Your Eloquent query executed by using get()

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

Je pense que les requêtes les plus récentes seront au bas du tableau.

Vous aurez quelque chose comme ça:

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

(Merci au commentaire de Joshua ci-dessous.)

jfortunato
la source
2
hmm je ne suis pas sûr mais vous pourrez peut-être accompagner ce que vous voulez avec un package compositeur stackoverflow.com/a/17339752/813181
jfortunato
9
Il pourrait même être préférable de le LogLog::debug(DB::getQueryLog())
publier dans
35
Vous devrez peut-être l'activer car il est désactivé par défaut maintenant. Vous pouvez utiliser cette commande pour l'activer temporairement:DB::enableQueryLog();
Joshua Fricke
5
J'ai essayé ta réponse. Ce que j'ai essayé c'est DB::enableQueryLog(); dd(DB::getQueryLog());Mais ça revient juste []....
Je suis la personne la plus stupide
6
Si vous avez plusieurs bases de données, vous devrez peut-être le faireDB::connection('database')->getQueryLog()
Damien Ó Ceallaigh
745

Utilisez la toSql()méthode sur une QueryBuilderinstance.

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

sélectionnez * parmi `utilisateurs`

C'est plus facile que de câbler un écouteur d'événements, et vous permet également de vérifier à quoi ressemblera la requête à tout moment pendant que vous la construisez.

Steven Mercatante
la source
6
Je pense que c'est la façon la plus simple d'utiliser Eloquent en dehors de Laravel
Gab
8
@Stormsson Ce n'est pas possible car PHP n'a jamais la requête avec les liaisons remplacées par leurs valeurs. Pour obtenir les requêtes dans leur intégralité, vous devez les enregistrer à partir de MySQL. Il y a plus d'informations ici: stackoverflow.com/questions/1786322/…
Matthew
40
@Stormsson, vous pouvez utiliser la getBindingsméthode. Cela retournera les liaisons afin qu'elles soient liées à l'instruction SQL.
danronmoon
2
Très utile pour déboguer des requêtes complexes qu'Eloquent refuse d'exécuter car celles-ci n'apparaissent pas dans le journal des requêtes.
BobChao87
34
Pour obtenir une requête avec bindinds$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
Ennio Sousa
88

DB::QueryLog()ne fonctionne qu'après avoir exécuté la requête $builder->get(). si vous souhaitez obtenir la requête avant d'exécuter la requête, vous pouvez utiliser la $builder->toSql()méthode. voici l'exemple pour obtenir le sql et le lier:

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

    $result = $builder->get();

OU faites simplement votre erreur de requête comme appeler une table ou une colonne inexistante, vous verrez la requête générée dans l'exception XD

Kakashi
la source
3
C'est, de loin, la meilleure réponse, simple et directe. Merci :)
Sobakus
18
En one-liner:$query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
kramer65
Cela devrait être inclus dans le cadre en tant que fonction native .. merci
Tomáš Mleziva
Notez que cela ne fonctionnera pas si votre requête a déjà des signes de pourcentage comme pour une LIKErequête ou lors du formatage des dates. Vous devrez d'abord échapper à ces premiers avec des signes de double pour cent.
The Unknown Dev
Y a-t-il des problèmes de sécurité lors de cette opération? Les fixations sont-elles désinfectées $builder->getBindings()?
solidau
56

Vous pouvez écouter l'événement «illuminate.query». Avant la requête, ajoutez l'écouteur d'événement suivant:

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

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

Cela imprimera quelque chose comme:

array(4) {
  [0]=>
  string(21) "select * from "users""
  [1]=>
  array(0) {
  }
  [2]=>
  string(4) "0.94"
  [3]=>
  string(6) "sqlite"
}
Rubens Mariuzzo
la source
1
J'obtiens Appel à la méthode non définie Illuminate \ Database \ Query \ Builder :: listen () dans Laravel 4
Miguel Stevens
2
Merci c'est super. Il est bon de noter que dd est une fonction qui produit un vidage de la variable donnée et termine l'exécution du script et également celle d'importer un événement, notammentuse Illuminate\Support\Facades\Event;
radtek
1
@radtek: Au lieu de use Illuminate\Support\Facades\Event;vous, vous pouvez simplement le faire use Event;car c'est une façade .
TachyonVortex
50

Si vous essayez d'obtenir le journal en utilisant Illuminate sans utiliser Laravel:

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

Vous pouvez également créer une fonction rapide comme ceci:

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

ÉDITER

les versions mises à jour semblent avoir la journalisation des requêtes désactivée par défaut (ce qui précède renvoie un tableau vide). Pour réactiver, lors de l'initialisation du gestionnaire de capsules, récupérez une instance de la connexion et appelez la enableQueryLogméthode

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

MODIFIER ENCORE

En tenant compte de la question réelle, vous pouvez réellement effectuer les opérations suivantes pour convertir la requête unique actuelle au lieu de toutes les requêtes précédentes:

$sql = $query->toSql();
$bindings = $query->getBindings();
Luke Snowden
la source
je reçois ce type de retour de la requête "name = [{" name ":" rifat "}]" que dois-je faire pour obtenir "name = rifat" uniquement?
incorporel
Je voudrais imprimer vos liaisons, on dirait que vous passez un tableau au lieu d'une chaîne
Luke Snowden
C'est un début utile, mais il semble négliger d'ajouter des guillemets simples autour des valeurs paramétrées, comme lorsque je passe une chaîne comme 'US/Eastern'.
Ryan
1
@Ryan, c'est vrai, c'est pourquoi j'ai déclaré quick function. Je crois que le code sous-jacent utilisera les méthodes prepare ( php.net/manual/en/mysqli.prepare.php ), c'est pourquoi juste la ?est requise. Vous pouvez php.net/manual/en/function.is-numeric.php pour déterminer s'il faut encapsuler ou non l'entrée dans des guillemets simples.
Luke Snowden
1
@LukeSnowden Votre réponse est géniale! J'ai finalement pris le temps d'essayer votre nouvelle version (que j'ai éditée ci-dessus pour inclure votre is_numericidée), et ça marche! J'aime cela. Je vous remercie.
Ryan
36

Il existe une méthode éloquente pour obtenir la chaîne de requête.

toSql ()

dans notre cas,

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

revenir

select * from users

est la solution exacte qui renvoie la chaîne de requête SQL. J'espère que cela sera utile ...

CelinVeronicca
la source
11
qu'en est-il des liaisons de requête? par exemple, lorsque vous faites un ->where('foo', '=', 'bar')bar ne montrera pas dans le sql
Toskan
28
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
Kuldeep Mishra
la source
Ceci est beaucoup plus précis, contrôlé et répond au besoin de la question.
benjaminhull
Merci pour votre commentaire.
Kuldeep Mishra
2
Vous pouvez ajouter ->toSql()comme vous le feriez s'il y a plus d'arguments après le modèle. par exempleUser::where('id', 1)->toSql()
Toby Mellor
24

Si vous utilisez laravel 5.1 et MySQL, vous pouvez utiliser cette fonction faite par moi:

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

En tant que paramètre d'entrée, vous pouvez utiliser l'un de ces paramètres

Illuminate \ Database \ Eloquent \ Builder

Illuminate \ Database \ Eloquent \ Relations \ HasMany

Illuminate \ Database \ Query \ Builder

Yevgeniy Afanasyev
la source
Réponse améliorée pour inclure toutes les remarques faites dans les commentaires. Merci beaucoup.
Yevgeniy Afanasyev
13

Vous devez d'abord activer le journal des requêtes en appelant:

DB::enableQueryLog();

après des requêtes utilisant la façade DB, vous pouvez écrire:

dd(DB::getQueryLog());

la sortie aimera ci-dessous:

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
la source
réponse très utile
Anoop PS
salut j'ai utilisé $ result = DB :: select ('select * from sqrt_user_modules where user_id =: id', ['id' => $ user]); DB :: enableQueryLog (); mais n'a obtenu aucune sortie dd (DB :: getQueryLog ());
Anoop PS
avons-nous besoin d'inclure une bibliothèque
Anoop PS
1
Étape 1: DB :: enableQueryLog (); étape 2: $ resultat = DB :: select ('select * from sqrt_user_modules where user_id =: id', ['id' => $ user]); étape 3: dd (DB :: getQueryLog ());
Ravi Mane
12

C'est la meilleure solution que je puisse suggérer à quiconque pour le débogage de la dernière requête éloquente ou de la requête finale, bien que cela ait également été discuté:

// 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
la source
10

Première voie:

Vous pouvez simplement faire les choses suivantes en utilisant la toSql()méthode,

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

echo $query->toSql();

Si cela ne fonctionne pas, vous pouvez configurer la chose à partir de la documentation de laravel .

Deuxième voie:

Une autre façon de procéder est

DB::getQueryLog()

mais s'il renvoie un tableau vide, il est désactivé par défaut, visitez ceci ,

il suffit d'activer avec DB::enableQueryLog()et cela fonctionnera :)

pour plus d'informations, visitez Github Issue pour en savoir plus.

J'espère que cela aide :)

Sagar Naliyapara
la source
10

Un remplacement «macroable» pour obtenir la requête SQL avec les liaisons.

  1. Ajouter la fonction macro ci-dessous dans la méthode.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. Ajoutez un alias pour Eloquent Builder. ( Laravel 5.4+ )

    \Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
        return ($this->getQuery()->toRawSql());
    });
  3. Déboguez ensuite comme d'habitude. ( Laravel 5.4+ )

    Par exemple, Query Builder

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

    Par exemple, Eloquent Builder

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

Remarque: de Laravel 5.1 à 5.3, puisque Eloquent Builder ne fait pas usage de la Macroablecaractéristique, ne peut pas ajouter toRawSqlun alias à Eloquent Builder à la volée. Suivez l'exemple ci-dessous pour obtenir le même résultat.

Par exemple Eloquent Builder ( Laravel 5.1 - 5.3 )

\Log::debug(\App\User::limit(1)->getQuery()->toRawSql());
Ijas Ameenudeen
la source
Oups, je suis arrivé en retard. Je veux juste soumettre une réponse en utilisant Macro. Ceci est la meilleure réponse. Doit être la réponse acceptée: D
nmfzone
Vous pouvez
résumer
8

utiliser le package debugbar

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

entrez la description de l'image ici

panqingqiang
la source
7

De laravel 5.2et au- delà . vous pouvez utiliser DB::listenpour obtenir des requêtes exécutées.

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

Ou si vous souhaitez déboguer une seule Builderinstance, vous pouvez utiliser la toSqlméthode.

DB::table('posts')->toSql(); 
Zayn Ali
la source
1
L'écoute est utile, déclarez-la avant d'exécuter la requête et videz le sql et les liaisons dans la méthode. Imparfait mais fonctionne plus rapidement / plus facilement que les autres réponses.
Andrew
7

Le moyen le plus simple consiste à commettre une erreur délibérée . Par exemple, je veux voir la requête SQL complète de la relation suivante:

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

Je viens de faire une colonne pour ne pas être trouvée, ici je choisis created_atet je l'ai modifiée created_atsen ajoutant la fin sà:

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

Ainsi, le débogueur renverra l'erreur suivante:

(4/4) ErrorException SQLSTATE [42S22]: colonne non trouvée: 1054 Unknown column 'eqtype_jobs.created_ats' dans 'liste des champs' (SQL: sélectionnez jobs*,. eqtype_jobs. set_idComme pivot_set_id, eqtype_jobs. job_idComme pivot_job_id, eqtype_jobs. created_ats Comme pivot_created_ats, eqtype_jobs. updated_atQue pivot_updated_at, eqtype_jobs. idQue pivot_idde jobsjointure interne eqtype_jobssur jobs. id= eqtype_jobs. job_ideqtype_jobs. set_id= 56 commande par la pivot_created_atlimite de décalage desc 20 0) (Voir: /home/said/www/factory/resources/views/set/show.blade.php)

Le message d'erreur ci-dessus renvoie la requête SQL complète avec l'erreur

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

Maintenant, supprimez simplement le supplément sde created_at et testez ce SQL comme vous le souhaitez dans n'importe quel éditeur SQL tel que l'éditeur SQL phpMyAdmin!

Remarquer:

La solution a été testée avec Laravel 5.4 .

SaidbakR
la source
2
C'est de loin la meilleure réponse! Si simple! :)
Picard
Cela ne montrera pas la requête avec des liaisons, c'est-à-dire que les liaisons s'afficheront comme:id
Shantha Kumara
@ShanthaKumara En effet, je ne sais pas quelle est la version ou la configuration de Laravel que vous avez utilisée. Cependant, chaque extrait ou code de ma réponse a été copié et collé à partir de la sortie de code réel du projet Laravel 5.4.
SaidbakR
6

Pour voir la requête exécutée par Laravel, utilisez le journal des requêtes de Laravel

DB::enableQueryLog();

$queries = DB::getQueryLog();
Jasim Juwel
la source
6

A partir de Laravel 5.8.15 le générateur de requêtes a maintenant dd et dumpméthodes afin que vous puissiez faire

DB::table('data')->where('a', 1)->dump();
Greg
la source
Merci. dd fonctionne vraiment bien. DB :: table ('data') -> où ('a', 1) -> dd ();
Waqas
Mieux que les autres réponses listées.
Hamees A. Khan
5

C'est la fonction que j'ai placée dans ma classe de modèle de base. Passez simplement l'objet générateur de requêtes dedans et la chaîne SQL sera retournée.

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
la source
4

Pour laravel 5.5.X

Si vous souhaitez recevoir chaque requête SQL exécutée par votre application, vous pouvez utiliser la méthode listen. Cette méthode est utile pour la journalisation des requêtes ou le débogage. Vous pouvez enregistrer votre écouteur de requêtes chez un fournisseur de services:

<?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()
    {
        //
    }
}

La source

scre_www
la source
4

Ajoutez cette fonction à votre application et appelez simplement.

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

Sortie : "sélectionnez * d' userlang= 'en' et status= '1' ordre par updated_atdesc limite 25 offset 0"

Dharmik
la source
3

Vous pouvez utiliser ce package pour obtenir toutes les requêtes qui s'exécutent lorsque vous chargez votre page

https://github.com/barryvdh/laravel-debugbar
Lakhwinder Singh
la source
Ce package est bon lorsque vous n'avez pas d'erreurs de requête. Si vous avez une erreur SQL, elle n'affichera rien
lewis4u
3

Imprimer la dernière requête

DB::enableQueryLog();

$query        = DB::getQueryLog();
$lastQuery    = end($query);
print_r($lastQuery);
Sohomdeep Paul
la source
2

Si vous n'utilisez pas Laravel mais utilisez le package Eloquent alors:

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
la source
2

vous pouvez utiliser le mouvement d'horlogerie

Clockwork est une extension Chrome pour le développement PHP, étendant les outils de développement avec un nouveau panneau fournissant toutes sortes d'informations utiles pour le débogage et le profilage de vos applications PHP, y compris des informations sur la demande, les en-têtes, obtenir et publier des données, cookies, données de session, requêtes de base de données, itinéraires, visualisation de l'exécution des applications et plus encore.

mais fonctionne aussi dans firefox

wdog
la source
2

J'ai créé quelques fonctions simples pour obtenir le SQL et les liaisons de certaines requêtes.

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

Usage:

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
la source
2

Autant que j'aime ce cadre, je déteste quand il agit comme de la merde.

DB::enableQueryLog()est totalement inutile. DB::listenest également inutile. Cela a montré une partie de la requête lorsque j'ai dit $query->count(), mais si je le fais $query->get(), cela n'a rien à dire.

La seule solution qui semble fonctionner de manière cohérente consiste à mettre intentionnellement une syntaxe ou une autre erreur dans les paramètres ORM, comme un nom de colonne / table inexistant, à exécuter votre code sur la ligne de commande en mode débogage, et il crachera l'erreur SQL avec la requête frickin complète enfin. Sinon, nous espérons que l'erreur apparaîtra dans le fichier journal si elle est exécutée à partir du serveur Web.

Spencer Williams
la source
Le journal des requêtes fonctionne très bien pour moi au moins. Vous devriez avoir d'autres erreurs dans votre application
user1415066
1

Si vous utilisez le bricoleur et que vous souhaitez enregistrer la requête SQL formée, vous pouvez le faire

$ 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
la source
1

Essaye ça:

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

Remarque: get () a été remplacé par toSql () pour afficher la requête SQL brute.

Nikhil Gyan
la source
1

Ma façon de faire cela, basée sur la vue du journal, n'a qu'à modifier le fichier app/Providers/AppServiceProvider.php:

  1. Ajoutez ce code dans 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. Mon code de poignée SQL:
$users = DB::table('users')
    ->select(DB::raw('count(*) as user_count, username '))
    ->where('uid', '>=', 10)
    ->limit(100)
    ->groupBy('username')
    ->get()
;
dd($users);
  1. Voir journal 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
la source