Como extrair SQL do Query Builder em string: guia completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Quando o Query Builder fica em silêncio e você precisa ver o SQL

\n\n

Você já escreveu uma consulta complexa usando o Query Builder, executou — e recebeu um erro ou dados inesperados? Dá aquela coceira de ver o que realmente está sendo gerado pela sua cadeia de métodos, mas o framework teima em retornar um objeto, não uma string. Situação familiar?

\n\n

Essa é uma das perguntas mais populares no Stack Overflow (dezenas de milhares de visualizações). E não é à toa. Saber "extrair" o SQL bruto do Query Builder é um superpoder que economiza horas de depuração. Especialmente quando você trabalha com ORMs como Doctrine ou Eloquent no Laravel, onde as consultas são construídas através de uma cadeia de métodos e o SQL real fica escondido.

\n\n

Neste artigo, vamos mostrar como obter a string SQL bruta do Query Builder em diferentes frameworks PHP, com exemplos de código e explicações sobre por que isso é importante para todo desenvolvedor. Vamos nessa!

\n\n

1. Por que você pode precisar do SQL bruto?

\n\n

Antes de mergulharmos no código, vamos entender por que vale a pena dar uma olhada no SQL "cru", se o Query Builder já faz tudo por nós.

\n\n
    \n
  • Depuração de erros. Quando a consulta não funciona, você vê apenas um objeto. Já o SQL é a verdade. Você enxerga quais tabelas estão sendo unidas (JOINs), quais condições WHERE estão sendo aplicadas e onde está o erro de sintaxe.
  • \n
  • Otimização de performance. O Query Builder pode gerar uma consulta ineficiente. Ao examiná-la, você perceberá JOINs desnecessários ou a falta de índices.
  • \n
  • Aprendizado. Se você é iniciante, ver o SQL gerado ajuda a entender como o ORM traduz seus métodos PHP em comandos SQL reais.
  • \n
  • Exportação e logging. Às vezes, é preciso registrar a consulta em um log ou enviá-la para outro serviço. Sem a string, isso é impossível.
  • \n
\n\n

Agora, vamos ao que interessa — o código.

\n\n

2. Laravel Eloquent: toSql() e getBindings()

\n\n

Laravel é o framework PHP mais popular, e seu Query Builder (parte do Eloquent) oferece métodos nativos para obter o SQL. Veja como funciona.

\n\n

Exemplo simples: toSql()

\n\n
use Illuminate\\Support\\Facades\\DB;\n\n$query = DB::table('users')\n    ->where('age', '>', 18)\n    ->where('status', 'active')\n    ->orderBy('name', 'asc');\n\n$sql = $query->toSql();\n\necho $sql;\n// Saída: select * from `users` where `age` > ? and `status` = ? order by `name` asc
\n\n

Perfeito! Mas você reparou nos pontos de interrogação? São placeholders para consultas preparadas. Para ver os valores reais, use getBindings().

\n\n

SQL completo com substituição de valores

\n\n
$bindings = $query->getBindings();\n\n$fullSql = vsprintf(str_replace('?', '%s', $sql), array_map(function ($value) {\n    return is_numeric($value) ? $value : "'" . $value . "'";\n}, $bindings));\n\necho $fullSql;\n// Saída: select * from `users` where `age` > 18 and `status` = 'active' order by `name` asc
\n\n

Esse truque substitui os placeholders pelos valores reais. Mas cuidado: não use este método para executar a consulta — ele não escapa os dados, serve apenas para depuração.

\n\n

Método dd() para depuração rápida

\n\n

No Laravel, existe o método prático dd() (dump and die), que exibe o SQL e os bindings:

\n\n
DB::table('users')->where('age', '>', 18)->dd();\n// Interrompe a execução e mostra:\n// sql: select * from `users` where `age` > ?\n// bindings: [18]
\n\n

Dica: Use dd() apenas em ambiente de desenvolvimento. Em produção, ele interrompe a consulta.

\n\n

3. Doctrine ORM: getSQL() e parâmetros

\n\n

Doctrine é um ORM poderoso, usado no Symfony e outros projetos. O Query Builder dele é um pouco diferente, mas o princípio é o mesmo.

\n\n

Exemplo básico

\n\n
use Doctrine\\ORM\\EntityManagerInterface;\n\n// Suponha que $entityManager já foi obtido via DI\n$queryBuilder = $entityManager->createQueryBuil                

Blogs

Book Recommendations