मैं एक स्ट्रिंग के रूप में अपने कच्चे एसक्यूएल क्वेरी को आउटपुट करने के लिए क्वेरी बिल्डर कैसे प्राप्त करूं?


544

निम्नलिखित कोड दिया गया है:

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

मैं कच्चे SQL क्वेरी स्ट्रिंग प्राप्त करना चाहता हूं जो ऊपर डेटाबेस क्वेरी बिल्डर उत्पन्न करेगा। इस उदाहरण में, यह होगा SELECT * FROM users

मैं यह कैसे करु?


14
लारवेल एलोक्वेंट ORM को कच्ची क्वेरी मिलती है:echo User::where('status', 1)->toSql();
मुहम्मद शहजाद

मैं लारवेल - टेलीस्कोप के लिए एक पैकेट का उपयोग कर रहा हूं, यह सभी प्रश्नों को लॉग करता है और कई और चीजें करता है।
विंस

जवाबों:


658

स्क्रीन पर आउटपुट के लिए अंतिम प्रश्न चले, आप इसका उपयोग कर सकते हैं:

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

// Your Eloquent query executed by using get()

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

मेरा मानना ​​है कि सबसे हाल के प्रश्न सरणी के निचले भाग में होंगे।

आपके पास कुछ ऐसा होगा:

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

( नीचे जोशुआ की टिप्पणी के लिए धन्यवाद ।)


2
hmm im यकीन नहीं है, लेकिन आप एक संगीतकार पैकेज stackoverflow.com/a/17339752/813181
jfortunato

9
Logकक्षा के उपयोग से इसे अपने एप्लिकेशन के लॉग में आउटपुट करना और भी बेहतर हो सकता है : Log::debug(DB::getQueryLog())
msturdy

35
अब इसे डिफ़ॉल्ट रूप से बंद करने के लिए आपको इसे सक्षम करने की आवश्यकता हो सकती है। आप इसे अस्थायी रूप से चालू करने के लिए इस कमांड का उपयोग कर सकते हैं:DB::enableQueryLog();
जोशुआ फ्रिक

5
मैंने आपके उत्तर की कोशिश की। मैंने जो कोशिश की है, DB::enableQueryLog(); dd(DB::getQueryLog());लेकिन यह अभी लौटता है []....
मैं

6
यदि आपके पास एक से अधिक डेटाबेस हैं, तो आपको करने की आवश्यकता हो सकती हैDB::connection('database')->getQueryLog()
डेमियन

744

उदाहरण toSql()पर विधि का उपयोग करें QueryBuilder

DB::table('users')->toSql() लौटूंगा:

`उपयोगकर्ताओं` से * का चयन करें

इवेंट श्रोता को तार-तार करने की तुलना में यह आसान है, और आपको यह जांचने की सुविधा भी देता है कि आप इसे बनाते समय किसी भी बिंदु पर क्वेरी वास्तव में कैसी दिखेगी।


6
मुझे लगता है कि लारवेल के बाहर एलोक्वेंट का उपयोग करते समय यह सबसे आसान तरीका है
गैब

8
@Stormsson यह संभव नहीं है क्योंकि PHP में बाइंडिंग के साथ उनके मूल्यों के साथ कभी भी क्वेरी नहीं होती है। संपूर्णता में प्रश्नों को प्राप्त करने के लिए आपको उन्हें MySQL से लॉग इन करना होगा। यहाँ अधिक जानकारी है: stackoverflow.com/questions/1786322/…
मैथ्यू

40
@ स्टॉर्मसन आप getBindingsविधि का उपयोग कर सकते हैं । यह बाइंडिंग वापस कर देगा ताकि वे SQL स्टेटमेंट के लिए बाध्य हों।
दानोनमून

2
जटिल प्रश्नों को डीबग करने के लिए बहुत उपयोगी है जो एलक्वेंट को उन लोगों के रूप में चलाने से मना करता है जो क्वेरी लॉग में दिखाई नहीं देते हैं।
BobChao87

33
बाइंडर्स के साथ क्वेरी प्राप्त करने के लिए$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
Ennio Sousa

88

DB::QueryLog()केवल क्वेरी निष्पादित करने के बाद ही कार्य करें $builder->get()। यदि आप क्वेरी का उपयोग $builder->toSql()करने से पहले क्वेरी प्राप्त करना चाहते हैं, तो आप विधि का उपयोग कर सकते हैं । यह उदाहरण है कि एसक्यूएल कैसे प्राप्त करें और इसे कैसे बांधें:

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

    $result = $builder->get();

या बस अपनी क्वेरी को त्रुटि दें जैसे कि अस्पष्टीकृत तालिका या स्तंभ के लिए कॉल करना, यू अपवाद XD में उत्पन्न क्वेरी को देखेंगे


3
यह, अब तक, सबसे अच्छा जवाब, सरल और सीधे बिंदु पर है। धन्यवाद :)
सोबाकस

18
एक लाइनर के रूप में:$query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
kramer65

इसे मूल कार्य के रूप में फ्रेमवर्क में शामिल किया जाना चाहिए .. धन्यवाद
Tomáš Mleziva

ध्यान दें कि यह काम नहीं करेगा यदि आपकी क्वेरी में पहले से ही प्रतिशत जैसे कि किसी LIKEक्वेरी के लिए या दिनांक स्वरूपित करते समय। आपको पहले दो प्रतिशत संकेतों के साथ भागने की आवश्यकता होगी।
अज्ञात देव

क्या ऐसा करते समय सुरक्षा चिंताएं हैं? क्या बाइंडिंग से स्वच्छता आती है $builder->getBindings()?
सॉलिडौ

56

आप 'illuminate.query' घटना सुन सकते हैं। क्वेरी से पहले निम्न ईवेंट श्रोता जोड़ें:

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

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

यह कुछ इस तरह प्रिंट करेगा:

array(4) {
  [0]=>
  string(21) "select * from "users""
  [1]=>
  array(0) {
  }
  [2]=>
  string(4) "0.94"
  [3]=>
  string(6) "sqlite"
}

1
मुझे अपरिभाषित विधि के लिए कॉल मिलता है। लारावेल 4 में सुनो (डेटाबेस) बिल्डर :: सुनो ()
मिगुएल स्टीवंस

2
धन्यवाद यह बहुत अच्छा है। यह नोट करने के लिए अच्छा है कि dd एक फ़ंक्शन है जो स्क्रिप्ट के दिए गए चर और अंत निष्पादन को डंप करता है और यह भी कि इवेंट को आयात करने के लिए, इसमें शामिल हैंuse Illuminate\Support\Facades\Event;
radtek

1
@radtek: इसके बजाय use Illuminate\Support\Facades\Event;आप बस कर सकते हैं use Event;क्योंकि यह एक मुखौटा है
TachyonVortex

50

यदि आप लारवेल के उपयोग के बिना इल्यूमिनेट का उपयोग करके लॉग प्राप्त करने की कोशिश कर रहे हैं:

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

आप भी इस तरह एक त्वरित कार्य कर सकते हैं:

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

संपादित करें

लगता है कि अपडेट किए गए संस्करण डिफ़ॉल्ट रूप से क्वेरी लॉगिंग अक्षम हैं (ऊपर एक खाली सरणी देता है)। कैप्सूल मैनेजर को इनिशियलाइज़ करते समय वापस चालू करने के लिए, कनेक्शन का एक उदाहरण लें और enableQueryLogविधि को कॉल करें

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

संपादित करें

वास्तविक प्रश्न को ध्यान में रखते हुए, आप वास्तव में सभी पिछले प्रश्नों के बजाय वर्तमान एकल क्वेरी को परिवर्तित करने के लिए निम्नलिखित कर सकते हैं:

$sql = $query->toSql();
$bindings = $query->getBindings();

मुझे क्वेरी "name = [{" name ":" rifat "}] से इस प्रकार का रिटर्न मिल रहा है। मुझे केवल" name = rifat "प्राप्त करने के लिए क्या करना होगा?
शामिल करें

मैं आपकी बाइंडिंग छपवाता हूँ, ऐसा लगता है जैसे आप एक स्ट्रिंग के बजाय एक
ल्यूक स्नोडेन

यह एक उपयोगी शुरुआत है, लेकिन यह पैरामीटर मानों के आसपास एकल उद्धरण जोड़ने के लिए उपेक्षा करने लगता है, जैसे कि जब मैं एक स्ट्रिंग पास करता हूं 'US/Eastern'
रायन

1
@ यह सच है इसलिए मैंने कहा था quick function। मेरा मानना ​​है कि अंतर्निहित कोड तैयार ( php.net/manual/en/mysqli.prepare.php ) विधियों का उपयोग करेगा , यही कारण है कि बस ?आवश्यकता है। आप सिंगल कोट्स के भीतर इनपुट को एनकैप्सुलेट कर सकते हैं या नहीं, यह निर्धारित करने के लिए आप php.net/manual/en/function.is-numeric.php कर सकते हैं ।
ल्यूक स्नोडेन

1
@LukeSnowden आपका जवाब प्रतिभाशाली है! मैंने अंततः आपके नए संस्करण को आज़माने के लिए समय लिया (जो मैंने आपके is_numericविचार को शामिल करने के लिए ऊपर संपादित किया है), और यह काम करता है! मुझे यह पसंद है। धन्यवाद।
रयान

36

क्वेरी स्ट्रिंग प्राप्त करने के लिए वाक्पटु में एक विधि है।

toSql ()

हमारे मामले में,

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

वापसी

select * from users

एसक्यूएल क्वेरी स्ट्रिंग को वापस लाने का सटीक उपाय है..इस मदद के लिए ...


11
क्वेरी बाइंडिंग के बारे में क्या? जैसे जब आप ->where('foo', '=', 'bar')sql में बार
वॉन्ट

28
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model

यह बहुत अधिक सटीक, नियंत्रित और प्रश्न की आवश्यकता को पूरा करता है।
बेंजामिनहुल

आपकी टिप्पणी के लिये धन्यवाद।
कुलदीप मिश्रा

2
यदि आप ->toSql()मॉडल के बाद अधिक तर्क हैं, तो आप कर सकते हैं। जैसेUser::where('id', 1)->toSql()
टोबी मेलर

24

यदि आप लार्वा 5.1 और MySQL का उपयोग करते हैं तो आप मेरे द्वारा किए गए इस फ़ंक्शन का उपयोग कर सकते हैं:

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

इनपुट पैरामीटर के रूप में आप इनमें से किसी एक का उपयोग कर सकते हैं

रोशन \ डाटाबेस \ सुवक्ता \ बिल्डर

रोशन \ डाटाबेस \ सुवक्ता \ संबंध \ HasMany

रोशन \ डाटाबेस \ क्वेरी \ बिल्डर


टिप्पणियों में किए गए सभी टिप्पणियों को शामिल करने के लिए उत्तर में सुधार हुआ। आपका बहुत बहुत धन्यवाद।
येवगेनी अफानसैयेव

13

पहले आपको कॉल करके क्वेरी लॉग को सक्षम करना होगा:

DB::enableQueryLog();

DB मुखौटा के उपयोग के बाद आप लिख सकते हैं:

dd(DB::getQueryLog());

उत्पादन नीचे की तरह होगा:

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

बहुत ही उपयोगी उत्तर
अनूप PS

hi मैंने $ result = DB का उपयोग किया है: select ('sqrt_user_modules से चयन करें * जहाँ user_id =: id', ['id' => $ user]); डीबी :: enableQueryLog (); लेकिन कोई आउटपुट dd नहीं मिलता (DB :: getQueryLog ());
अनूप पीएस

क्या हमें किसी भी पुस्तकालय को शामिल करने की आवश्यकता है
अनूप PS

1
चरण 1: DB :: enableQueryLog (); चरण 2: $ परिणाम = DB :: चयन करें (जहां sqrt_user_modules से चयन करें * जहां user_id =: id ', [' id '=> $ उपयोगकर्ता]); चरण 3: dd (DB :: getQueryLog ());
रवि माने

12

यह सबसे अच्छा समाधान है जिसे मैं डिबग-इंग इलक्वेंट अंतिम प्रश्न या अंतिम प्रश्न के लिए किसी को भी सुझा सकता हूं, हालांकि इस पर भी चर्चा की गई है:

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

पहला तरीका:

बस आप toSql()विधि का उपयोग कर निम्नलिखित सामान कर सकते हैं ,

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

echo $query->toSql();

यदि यह काम नहीं कर रहा है तो आप लार्वा प्रलेखन से बात सेट कर सकते हैं ।

दूसरा तरीका:

इसे करने का एक और तरीका है

DB::getQueryLog()

लेकिन अगर यह एक खाली सरणी देता है, तो डिफ़ॉल्ट रूप से यह अक्षम है , इस पर जाएं ,

बस के साथ सक्षम है DB::enableQueryLog()और यह काम करेगा :)

अधिक जानकारी के लिए Github जारी करें इसके बारे में अधिक जानने के करें।

आशा है ये मदद करेगा :)


10

बाइंडिंग के साथ SQL क्वेरी प्राप्त करने के लिए 'मैक्रोबल' प्रतिस्थापन।

  1. में मैक्रो फ़ंक्शन के नीचे जोड़ें 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. एलोकेन्ट बिल्डर के लिए एक उपनाम जोड़ें। ( लारवेल 5.4+ )

    \Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
        return ($this->getQuery()->toRawSql());
    });
  3. फिर हमेशा की तरह डिबग करें। ( लारवेल 5.4+ )

    जैसे क्वैरी बिल्डर

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

    एग एलोकेंट बिल्डर

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

नोट: लारवेल 5.1 से 5.3 के बीच, चूंकि एलोकेंट बिल्डर का उपयोग नहीं होता है Macroable ट्रेटtoRawSql फ्लाई पर एलोकेन्ट बिल्डर में एक उपनाम नहीं जोड़ सकता है । उसी को प्राप्त करने के लिए नीचे दिए गए उदाहरण का अनुसरण करें।

एग एलीकेंट बिल्डर ( लारवेल 5.1 - 5.3 )

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

वाह, मैं देर से आया। बस मैक्रो का उपयोग करके जवाब प्रस्तुत करना चाहते हैं। यह सबसे अच्छा जवाब है। स्वीकृत उत्तर होना चाहिए: D
nmfzone

आप बेस पर एक दायरे में उत्तरार्द्ध को दूर कर सकते हैं मॉडल
ओगियर स्कैल्विस

8

डीबगर पैकेज का उपयोग करें

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

यहाँ छवि विवरण दर्ज करें


7

लार्वा 5.2और आगे से। आप DB::listenनिष्पादित प्रश्नों को प्राप्त करने के लिए उपयोग कर सकते हैं ।

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

या यदि आप किसी एक Builderउदाहरण को डीबग करना चाहते हैं तो आप toSqlविधि का उपयोग कर सकते हैं ।

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

1
सुनने वाली बात उपयोगी है, क्वेरी चलाने से पहले इसे घोषित करें, और विधि के भीतर sql & bindings को डंप करें। अपूर्ण लेकिन अन्य उत्तरों की तुलना में तेज / आसान काम करता है।
एंड्रयू

7

सबसे आसान तरीका जानबूझकर गलती करना है । उदाहरण के लिए, मैं निम्नलिखित संबंध की पूर्ण SQL क्वेरी देखना चाहता हूं:

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

मैं बस एक कॉलम बनाने के लिए नहीं पाया जा सकता है, यहाँ मैं चुनता created_atहूं और मैंने इसे बदलने के लिए इसे created_atsजोड़कर बदल दिया sहै:

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

इसलिए, डिबगर निम्न त्रुटि लौटाएगा:

(4/4) ErrorException SQLSTATE [42S22]: नहीं मिला कॉलम: 1054 अज्ञात स्तंभ 'फ़ील्ड सूची' में 'eqtype_jobs.created_ats' (एसक्यूएल: चयन jobs*,। eqtype_jobsset_idके रूप में pivot_set_id, eqtype_jobsjob_idके रूप में pivot_job_id, eqtype_jobscreated_ats के रूप में pivot_created_ats, eqtype_jobsupdated_atके रूप में pivot_updated_at, eqtype_jobsidके रूप में pivot_idसे jobsभीतरी में शामिल होने eqtype_jobsपर jobsid= eqtype_jobsjob_idजहां eqtype_jobsset_id= 56 आदेश से pivot_created_atdesc सीमा 20 ऑफसेट 0) (दृश्य: /home/said/www/factory/resources/views/set/show.blade.php)

उपरोक्त त्रुटि संदेश गलती से पूर्ण SQL क्वेरी देता है

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

अब, screate_at से अतिरिक्त को हटा दें और इस SQL ​​का परीक्षण करें जैसे आप किसी SQL संपादक जैसे phpMyAdmin SQL संपादक में चाहते हैं!

नोटिस:

समाधान का परीक्षण Laravel 5.4 के साथ किया गया है ।


2
यह अब तक का सबसे अच्छा जवाब है! बहुत आसन! :)
पिकार्ड

यह बाइंडिंग के साथ क्वेरी नहीं दिखाएगा, यानी बाइंडिंग जैसे दिखाई देगा:id
शांता कुमारा

@ शान्ताकुमार वास्तव में, मुझे नहीं पता कि लारवेल का वह संस्करण या विन्यास क्या है जिसका आपने उपयोग किया है। हालांकि, मेरे जवाब में प्रत्येक स्निपेट या कोड को लारवेल 5.4 परियोजना के वास्तविक कोड आउटपुट से कॉपी और पेस्ट किया गया था।
सईदबाकरा

6

लारवेल एक्सक्लूसिव क्वेरी को देखने के लिए लार्वेल क्वेरी लॉग का उपयोग करें

DB::enableQueryLog();

$queries = DB::getQueryLog();

6

Laravel 5.8.15 के अनुसार क्वेरी बिल्डर के पास अब dd और dumpविधियाँ हैं, ताकि आप कर सकें

DB::table('data')->where('a', 1)->dump();

धन्यवाद। dd वास्तव में अच्छी तरह से काम करता है। DB :: टेबल ('डेटा') -> कहाँ ('ए', 1) -> डी डी ();
वकास

सूचीबद्ध अन्य उत्तरों से बेहतर है।
हमीज़ ए। खान

5

यह फ़ंक्शन है, मैंने अपने बेस मॉडल वर्ग में रखा है। बस इसमें क्वेरी बिल्डर ऑब्जेक्ट को पास करें और SQL स्ट्रिंग वापस आ जाएगी।

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

5

मेरी राय में, यह एक शुरुआत के रूप में सबसे अच्छा तरीका होगा:

echo "<pre>";
print_r($query->toSql());
print_r($query->getBindings());

यह भी यहाँ दर्शाया गया है। https://stackoverflow.com/a/59207557/9573341


4

लार्वा 5.5.X के लिए

यदि आप अपने आवेदन द्वारा निष्पादित प्रत्येक SQL क्वेरी प्राप्त करना चाहते हैं, तो आप सुनने की विधि का उपयोग कर सकते हैं। यह विधि लॉगिंग क्वेरी या डीबगिंग के लिए उपयोगी है। आप अपने क्वेरी श्रोता को एक सेवा प्रदाता में पंजीकृत कर सकते हैं:

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

स्रोत


4

इस फ़ंक्शन को अपने एप्लिकेशन में जोड़ें और बस कॉल करें।

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

आउटपुट : "से * का चयन करें, userजहां से lang= 'एन' और status= order 1 'क्रम से updated_atdesc सीमा २५ ऑफसेट ०"


3

आप इस पैकेज का उपयोग उन सभी प्रश्नों को प्राप्त करने के लिए कर सकते हैं जो आपके पेज को लोड करते समय निष्पादित कर रहे हैं

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

जब आप क्वेरी में त्रुटि नहीं करते हैं तो यह पैकेज अच्छा है। यदि आपके पास SQL ​​त्रुटि है, तो यह कुछ भी नहीं दिखाएगा
lewis4u


2

यदि आप लारवेल का उपयोग नहीं कर रहे हैं लेकिन एलोकेंट पैकेज का उपयोग कर रहे हैं तो:

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

आप घड़ी की कल का उपयोग कर सकते हैं

घड़ी की कल PHP के विकास के लिए एक क्रोम एक्सटेंशन है, डेवलपर टूल को एक नए पैनल के साथ बढ़ाता है जो आपके PHP अनुप्रयोगों को डिबगिंग और प्रोफाइलिंग के लिए उपयोगी सभी प्रकार की जानकारी प्रदान करता है, जिसमें अनुरोध, हेडर, डेटा और कुकीज़, सत्र डेटा, डेटाबेस प्रश्नों के बारे में जानकारी शामिल है, मार्गों, आवेदन क्रम और अधिक के दृश्य।

लेकिन फ़ायरफ़ॉक्स में भी काम करता है


2

मैं कुछ सरल कार्यों बना लिया है कुछ प्रश्नों से एसक्यूएल और बाइंडिंग मिलता है।

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

उपयोग:

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

जितना मुझे इस ढांचे से प्यार है, मुझे उससे नफरत है जब यह बकवास की तरह काम करता है।

DB::enableQueryLog()पूरी तरह से बेकार है। DB::listenउतना ही बेकार है। जब मैंने कहा $query->count(), तो यह क्वेरी का हिस्सा था , लेकिन अगर मैं करता हूं$query->get() यह , तो यह कहने के लिए कुछ भी नहीं है।

लगातार काम करने के लिए प्रकट होने वाला एकमात्र समाधान ORM मापदंडों में जानबूझकर कुछ सिंटैक्स या अन्य त्रुटि डालना है, जैसे कि कोई भी बिना कॉलम वाला / तालिका नाम, डिबग मोड में अपना कोड कमांड लाइन पर चलाएं, और यह SQL त्रुटि को थूक देगा अंत में पूर्ण 'frickin क्वेरी के साथ। अन्यथा, उम्मीद है कि वेब सर्वर से चलने पर लॉग फ़ाइल में त्रुटि दिखाई देती है।


क्वेरी लॉग कम से कम मेरे लिए ठीक काम करता है। आपके आवेदन में कुछ अन्य त्रुटियां होनी चाहिए
user1415066

1

यदि आप टिंकर का उपयोग कर रहे हैं और SQL क्वेरी को लॉग करना चाहते हैं, तो आप कर सकते हैं

$ 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

इसे इस्तेमाल करे:

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

नोट: कच्चे SQL क्वेरी को प्रदर्शित करने के लिए get () को toSql () से बदल दिया गया है।


1

यह करने का मेरा तरीका, लॉग दृश्य के आधार पर, केवल फ़ाइल को संशोधित करने की आवश्यकता है app/Providers/AppServiceProvider.php:

  1. इस कोड को जोड़ें 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. मेरा sql हैंडल कोड:
$users = DB::table('users')
    ->select(DB::raw('count(*) as user_count, username '))
    ->where('uid', '>=', 10)
    ->limit(100)
    ->groupBy('username')
    ->get()
;
dd($users);
  1. लॉग देखें 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} 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.