쿼리 빌더가 원시 SQL 쿼리를 문자열로 출력하려면 어떻게 해야 합니까?
다음 코드가 지정됩니다.
DB::table('users')->get();
위의 데이터베이스 쿼리 작성기에서 생성할 원시 SQL 쿼리 문자열을 가져오고 싶습니다.이 예에서는 다음과 같습니다.SELECT * FROM users
.
이거 어떻게 해?
하다를 사용하세요.toSql()
의 QueryBuilder
★★★★★★ 。
DB::table('users')->toSql()
★★★★
"users"에서 *를 선택합니다.
이것은 이벤트청취자를 연결하는 것보다 쉽고, 작성하는 동안 어떤 시점에서 쿼리가 실제로 어떻게 표시되는지 확인할 수 있습니다.
이 빌더 할 수 있습니다.단, 이 메서드는 쿼리 빌더 및 웅변술에 사용할 수 있습니다.toSql()
.first()
★★★★★★★★★★★★★★★★★」get()
이 방법을 사용하면 쿼리를 실행하는 동시에 SQL을 가져올 수 없습니다.
마지막으로 실행된 쿼리를 화면에 출력하려면 다음을 사용합니다.
\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"
}
}
DB::QueryLog()
는 쿼리를 합니다.$builder->get()
.
하기 전 하지 않고 를 할 수 .$builder->toSql()
★★★★★★ 。
원시 SQL을 가져와 '?'를 실제 바인딩 값으로 바꾸는 예:
$query = str_replace(array('?'), array('\'%s\''), $builder->toSql());
$query = vsprintf($query, $builder->getBindings());
dump($query);
$result = $builder->get();
또는 존재하지 않는 테이블 또는 열을 사용하여 의도적으로 오류를 트리거할 수 있습니다.그런 다음 예외 메시지에서 생성된 쿼리를 볼 수 있습니다.
당신은 'luminate'를 들을 수 있습니다.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"
}
Larabel을 사용하지 않고 Illuminate를 사용하여 로그를 가져오려는 경우:
\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) :
if (is_bool($binding)) {
$val = $binding === true ? 'TRUE' : 'FALSE';
} else if (is_numeric($binding)) {
$val = $binding;
} else {
$val = "'$binding'";
}
$prep = preg_replace("#\?#", $val, $prep, 1);
endforeach;
$formattedQueries[] = $prep;
endforeach;
return $formattedQueries;
}
편집
업데이트된 버전은 기본적으로 쿼리 로깅이 비활성화되어 있는 것 같습니다(위의 경우 빈 배열이 반환됩니다).할 때 켜려면 를 합니다.enableQueryLog
$capsule::connection()->enableQueryLog();
다시 편집
실제 질문을 고려했을 때 이전 모든 쿼리가 아닌 현재 단일 쿼리를 변환하기 위해 실제로 다음을 수행할 수 있습니다.
$sql = $query->toSql();
$bindings = $query->getBindings();
웅변에는 쿼리 문자열을 가져오는 방법이 있습니다.
toSql()
저희 같은 경우에는
DB::table('users')->toSql();
돌아가다
select * from users
는 SQL 쿼리 문자열을 반환하는 정확한 솔루션입니다.이게 도움이 되길...
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
이것이 웅변적인 마지막 쿼리 또는 최종 쿼리를 디버깅하기 위해 제안할 수 있는 가장 좋은 해결책입니다.단, 이것도 설명했습니다.
// 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);
larabel 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;
}
입력 매개 변수로 다음 중 하나를 사용할 수 있습니다.
조명\데이터베이스\웅변가\빌더
조명\데이터베이스\웅변\관계\하스매니
조명\데이터베이스\쿼리\빌더
먼저 다음을 호출하여 쿼리 로그를 활성화해야 합니다.
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
]
]
바인딩과 함께 SQL 쿼리를 가져오기 위한 '매크로 가능' 대체입니다.
메서드에
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()); });
웅변가 빌더의 별칭을 추가합니다(Larabel 5.4+).
\Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){ return ($this->getQuery()->toRawSql()); });
그런 다음 평소대로 디버깅합니다.(Larabel 5.4+)
예: 쿼리 작성기
\Log::debug(\DB::table('users')->limit(1)->toRawSql())
예: 웅변가 빌더
\Log::debug(\App\User::limit(1)->toRawSql());
5.부터 5까지, Larabel 5.1을 하지 않기 에, Alustic Builder는 Larabel 5.1을 사용하지 않습니다.
Macroable
,할 수 , " " "toRawSql
을 얻으려면 .아래 예에 따라 동일한 결과를 얻으십시오.
예: 웅변가(Larabel 5.1~5.3)
\Log::debug(\App\User::limit(1)->getQuery()->toRawSql());
Larabel 5.8.15 현재 쿼리 빌더는 dd
★★★★★★★★★★★★★★★★★」dump
수 방법
DB::table('data')->where('a', 1)->dump();
첫 번째 방법:
단순히 방법을 사용하여 다음 작업을 수행할 수 있습니다.
$query = DB::table('users')->get();
echo $query->toSql();
정상적으로 동작하지 않는 경우는, 라라벨의 메뉴얼로부터 셋업 할 수 있습니다.
두 번째 방법:
또 다른 방법은
DB::getQueryLog()
그러나 빈 어레이가 반환되면 기본적으로는 비활성화되어 있습니다.
just enable with 을 유효하게 하다DB::enableQueryLog()
그리고 그것은 뭔가요?
자세한 내용은 Github Issue를 참조하십시오.
도움이 되었으면 좋겠다:)
가장 쉬운 방법은 고의로 실수를 하는 것이다.예를 들어 다음과 같은 관계에 대한 전체 SQL 쿼리를 표시하려고 합니다.
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_at','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
찾을 수 있는 열을 만들기 위해 을 는 들 해 기 위 택 i just to선, found다 to i be not니,합 a make here만열찾없여서수기 choose column을created_at
and I changed it to 그래서 제가 그걸 바꿨어요.created_ats
by adding trailing 후행 추가에 의해s
…할 수 있다.
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_ats','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
따라서 디버거는 다음 오류를 반환합니다.
(4/4) 오류Ex 예외 SQL 상태: (42S22S22S22] 오류Ex 예외 SQL 상태: (42S22S22S22] 오류Ex 예외 SQL 상태:열(SQL_jq 유형_jq 유형_jq 유형_SQL 드 을 목 록)을 선택합니다.
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
부에서jobs
inner join 이너 조인트eqtype_jobs
on 에jobs
....id
= = =eqtype_jobs
....job_id
어 어디 있죠?eqtype_jobs
....set_id
= = 56 주 56 μmpivot_created_at
0) ( /factoryshowdesc limit 20 offset 0) (: / home/said/said/wwwwwwwww/fp)
위의 오류 메시지는 오류와 함께 전체 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
여분의, 제, 이, 이, 이, 이, remove, remove, remove, remove, remove, remove, remove, nows
에서 이 예: editor!created_at)에서합니다.
주의:
이 솔루션은 Larabel 5.4에서 테스트되었습니다.
초보자로서 이것이 최선의 접근법이라고 생각합니다.
echo "<pre>";
print_r($query->toSql());
print_r($query->getBindings());
이것 또한 여기에 묘사되어 있다.https://stackoverflow.com/a/59207557/9573341
이 기능을 응용 프로그램에 추가하고 전화를 걸기만 하면 됩니다.
function getQuery($sql){
$query = str_replace(array('?'), array('\'%s\''), $sql->toSql());
$query = vsprintf($query, $sql->getBindings());
return $query;
}
출력: "select * from"user
어디에lang
= 'en' 및status
= '1' 주문 기준updated_at
desc limit 25 오프셋 0"
이미 답변된 많은 정보가 있습니다. SQL 쿼리를 실행하기 전에 출력해야 할 때마다 사용하던 결과를 게시합니다.
아래 샘플에 대해 생각해 보십시오.
$user = DB::table('user')->where('id',1);
echo $user->toSql();
echo $user -> toSql() = raw 쿼리는 출력될 뿐 전달된 파라미터는 표시되지 않습니다.
전달된 파라미터를 사용하여 쿼리를 출력하려면 다음과 같이 laravel getBindings() 및 helper str_replace_array를 사용합니다.
$queryWithParam = str_replace_array('?',$user->getBindings(),$user->toSql());
echo $queryWithParam;
이것 또한 도움이 되길 바랍니다.
debugbar 패키지 사용
composer require "barryvdh/laravel-debugbar": "2.3.*"
라라벨에서5.2
그 이후로는요.사용할 수 있습니다.DB::listen
실행 쿼리를 가져옵니다.
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
또는 싱글을 디버깅하고 싶은 경우Builder
인스턴스(instance)를 사용할 수 있습니다.toSql
방법.
DB::table('posts')->toSql();
Larabel 실행 쿼리를 보려면 Larabel 쿼리 로그를 사용하십시오.
DB::enableQueryLog();
$queries = DB::getQueryLog();
이것은 기본 모델 클래스에 배치한 함수입니다.쿼리 빌더 객체를 전달하기만 하면 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;
}
가장 쉬운 방법인 toSql 메서드를 사용할 수 있습니다.
DB::table('users')->toSql();
또한 쿼리에 바인딩이 있고 바인딩이 있는 쿼리를 표시하려는 경우에도 마찬가지입니다.다음과 같은 것은 사용할 수 없습니다.
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$sql_with_bindings = str_replace_array('?', $query->getBindings(), $query->toSql());
dd($sql_with_bindings);
이것을 시험해 보세요.
$results = DB::table('users')->toSql();
dd($results);
주의: get()은 원시 SQL 쿼리를 표시하기 위해 toSql()로 대체되었습니다.
라라벨 5.5용.x
응용 프로그램에서 실행되는 각 SQL 쿼리를 수신하려면 listen 메서드를 사용할 수 있습니다.이 방법은 쿼리 로깅 또는 디버깅에 유용합니다.쿼리 리스너를 서비스 프로바이더에 등록할 수 있습니다.
<?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()
{
//
}
}
나는 이 틀을 좋아하지만, 그것이 쓰레기처럼 행동하는 것은 싫다.
DB::enableQueryLog()
전혀 쓸모가 없다. DB::listen
똑같이 쓸모없다.내가 말했을 때 질문의 일부를 보여줬어$query->count()
하지만 만약 내가 한다면$query->get()
할 말이 없습니다.
일관되게 기능하는 유일한 솔루션은 존재하지 않는 열/테이블 이름 등의 ORM 파라미터에 의도적으로 구문 또는 기타 오류를 삽입하여 디버깅모드일 때 명령줄에서 코드를 실행하는 것입니다.이것에 의해 최종적으로 완전한 frickin' 쿼리에서 SQL 오류가 발생합니다.그렇지 않으면 웹 서버에서 실행한 경우 로그 파일에 오류가 나타나기를 바랍니다.
실행된 모든 쿼리를 기록하려면 DB::enable을 사용합니다.QueryLog() icw DB::getQueryLog().출력의 구조는 다음과 같습니다.
[
[
"query" => "select * from "users" where name = ?"
"bindings" => ["John Doe"]
"time" => 0.34
],
...
]
또한 SQL과 컴파일된 바인딩을 해석하는 완벽한 함수를 얻기 위해 여기에 몇 가지 답변을 조합했습니다.이하를 참조해 주세요.이 기능을 구현하는 커스텀 빌더 클래스도 만들었습니다.사용자: where('name', John Doe')-> parse();
function parse_sql(string $sql, array $bindings) : string
{
$compiled_bindings = array_map('compile_binding', $bindings);
return preg_replace_array("/\?/", $compiled_bindings, $sql);
}
function compile_binding($binding)
{
$grammar = new MySqlGrammar;
if (is_bool($binding))
{
return (int)$binding; //This line depends on the database implementation
}
if(is_string($binding))
{
return "'$binding'";
}
if ($binding instanceof DateTimeInterface)
{
return $binding->format($grammar->getDateFormat());
}
return $binding;
}
이 패키지를 사용하여 페이지를 로드할 때 실행 중인 모든 쿼리를 가져올 수 있습니다.
https://github.com/barryvdh/laravel-debugbar
마지막 쿼리 인쇄
DB::enableQueryLog();
$query = DB::getQueryLog();
$lastQuery = end($query);
print_r($lastQuery);
tinker를 사용하여 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",
}
>>>
뷰에 파일을.app/Providers/AppServiceProvider.php
:
- 를 에 추가합니다.
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,
]
);
});
}
- 내 SQL 핸들 코드:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, username '))
->where('uid', '>=', 10)
->limit(100)
->groupBy('username')
->get()
;
dd($users);
- 「」
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}
언급URL : https://stackoverflow.com/questions/18236294/how-do-i-get-the-query-builder-to-output-its-raw-sql-query-as-a-string
'programing' 카테고리의 다른 글
에 초점을 맞출 수 있을까요?에 초점을 맞출 수 있을까요?JavaScript focus() 함수를 사용하고 있습니까? (0) | 2022.10.31 |
---|---|
Chrome DevTools의 요소에서 발생한 이벤트를 보려면 어떻게 해야 합니까? (0) | 2022.10.31 |
MySQL: 선택문의 임시 열을 자동으로 증가시킵니다. (0) | 2022.10.31 |
여러 개의 공백 제거 (0) | 2022.10.31 |
MySQL 테이블에서 열을 삭제하는 방법 (0) | 2022.10.31 |