8

Как вывести сырой SQL-запрос в виде строки из билдера запросов?

7

Пожалуйста, переведите ниже описание проблемы на русский язык для StackOverflow.com:


У меня есть следующий код:

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

Я хочу получить сырой SQL-запрос, который будет сгенерирован указанным конструктором запросов к базе данных. В этом примере это будет SELECT * FROM users.

Как мне это сделать?

5 ответ(ов)

11

Чтобы получить SQL-запрос из экземпляра QueryBuilder, вы можете использовать метод toSql(). Например, вызов:

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

возвратит:

select * from `users`

Это гораздо проще, чем настраивать слушателя событий, и также позволяет вам в любой момент проверить, как будет выглядеть запрос, пока вы его строите.

Обратите внимание: этот метод работает как для построителя запросов, так и для Eloquent, однако toSql() используется вместо first() или get(). Вы не можете выполнить запрос и одновременно получить SQL-оператор с помощью этого метода.

1

DB::QueryLog() работает только после выполнения запроса с помощью метода $builder->get().

Если вы хотите получить сырой SQL-запрос до или без его выполнения, вы можете использовать метод $builder->toSql().

Вот пример, как получить сырой SQL-запрос и заменить '?' на реальные значения привязки:

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

$result = $builder->get();

Кроме того, вы можете намеренно вызвать ошибку, например, используя несуществующую таблицу или столбец. В этом случае вы сможете увидеть сгенерированный запрос в сообщении исключения.

0

Вы можете прослушивать событие '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"
}

Таким образом, вы сможете отследить выполняемые запросы, параметры, время выполнения и используемое соединение. Это очень полезно для отладки.

0

Если вы пытаетесь получить журналы запросов, используя Illuminate без Laravel, вы можете использовать следующий код:

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

ИСПРАВЛЕНИЕ

В новых версиях, похоже, журналирование запросов по умолчанию отключено (вызов выше вернет пустой массив). Чтобы включить его обратно, при инициализации Capsule Manager получите экземпляр соединения и вызовите метод enableQueryLog:

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

СНОВА ИСПРАВЛЕНИЕ

Учитывая фактический вопрос, вы также можете сделать следующее, чтобы получить текущий один запрос вместо всех предыдущих:

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

В Eloquent есть метод для получения строки SQL запроса.

toSql()

В нашем случае:

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

возвращает

select * from users

это точное решение, которое возвращает строку SQL запроса. Надеюсь, это поможет...

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь