SQL original
SQL alterado

Diff SQL: Compare Dois Arquivos SQL Online

Cole, formate e compare duas consultas SQL ou arquivos de schema lado a lado. Funciona com PostgreSQL, MySQL, SQL Server, SQLite e Oracle.

O que é a ferramenta de diff SQL?

Uma ferramenta gratuita no navegador para comparar dois arquivos SQL. Cole um CREATE TABLE antigo à esquerda, o novo à direita, e as mudanças acendem caractere por caractere. Mesmo fluxo para duas versões de uma consulta analítica, uma instrução emitida por ORM, ou a saída de um pg_dump. Nada sai da sua máquina.

O diff é em nível de texto. Não parseia o SQL em uma AST e não entende equivalência semântica: SELECT a, b e SELECT b, a são lidos como diferentes pelo diff mesmo que ambos retornem as mesmas linhas em outra ordem. Para 95% das tarefas de revisão de código (migrações de schema, refatorações de consulta, comparação de saída de ORM) o diff de texto é o que você de fato quer, porque a ordem de colunas e cláusulas faz parte de como o time lê a mudança.

Se você já tentou achar a única cláusula WHERE nova em uma consulta analítica de 400 linhas que começou a retornar contagem de linhas diferente, esta é a ferramenta que te leva lá em segundos. Para prosa que não é SQL, nossa ferramenta de diff de texto é a escolha certa. Para payloads de resultado de ORM em JSON, JSON diff lida com reordenamento de objetos de forma mais limpa. Para exportações DDL antigas escritas como metadados XML, XML diff encaixa melhor.

Como o diff funciona de verdade

Por baixo dos panos, o diff roda em nível de caractere, e depois uma passada semântica desloca os destaques para que caiam sobre identificadores, palavras-chave e fronteiras de cláusulas em vez de pontuação aleatória. Inserções aparecem em verde à direita, remoções em vermelho à esquerda. Cada painel tem um botão Format que reformata o SQL com indentação consistente e uma instrução por linha, o que mata a maior parte do ruído de formatação antes da comparação.

SQL é uma família de dialetos, não uma única linguagem. O padrão ISO/IEC 9075 define uma gramática base, mas cada banco a estende: PostgreSQL tem strings com dollar-quoting e RETURNING, MySQL tem identificadores com backtick e ON DUPLICATE KEY UPDATE, SQL Server usa TOP e identificadores entre colchetes, SQLite tolera quase qualquer coisa, e Oracle tem ROWNUM e CONNECT BY. Fazer diff entre dialetos é tranquilo; a ferramenta não vai te avisar que um trecho é inválido em algum deles.

Outra coisa a saber: comparar o texto da consulta não é o mesmo que comparar os planos da consulta. Duas instruções com texto idêntico podem produzir planos muito diferentes com estatísticas diferentes, e duas instruções cosmeticamente diferentes podem produzir o mesmo plano. Para comparar planos, as ferramentas certas são EXPLAIN ANALYZE no psql ou o equivalente no seu cliente de banco (DataGrip, DBeaver, SSMS). Para revisão de refatoração textual, o diff é o que você quer. Leitura de fundo sobre a linguagem em si na Wikipédia.

Como comparar SQL em três passos

Dois painéis de texto, um diff. Sem cadastro, sem upload, sem ida e volta ao servidor.

  1. 1

    Cole ou faça upload do seu SQL

    Cole o SQL antigo à esquerda, o novo à direita. Ou clique em Upload em qualquer lado para carregar diretamente um arquivo .sql, .ddl ou .psql. O botão Sample preenche os dois painéis com um pequeno schema de orders se você quiser ver a ferramenta em ação primeiro.

  2. 2

    Formate ambos os lados para uma comparação justa

    Clique em Format em cada painel para reformatar o SQL com indentação consistente, uma instrução por linha e palavras-chave em maiúsculas. Isso mata o ruído de uma consulta formatada pelo DataGrip de um lado e uma escrita à mão do outro, então o diff destaca mudanças reais de schema e de cláusulas em vez de diferenças de espaçamento e caixa.

  3. 3

    Leia o diff

    Remoções aparecem destacadas em vermelho à esquerda, inserções em verde à direita. Role um lado e o outro acompanha. Os contadores de mudanças em cada cabeçalho dizem quantas edições distintas o diff achou em colunas, joins, predicados e elementos DDL.

Quando o diff SQL é a ferramenta certa

Revisar uma migração de schema antes de aplicar

Um PR de migração adiciona três colunas e ajusta dois índices. Cole o CREATE TABLE anterior contra o novo e as adições saltam aos olhos: foi adicionada uma coluna currency CHAR(3) NOT NULL sem DEFAULT, o que vai falhar em qualquer linha existente. Pegar isso antes da migração rodar contra produção, em vez de depois do alarme de deploy disparar às 2 da manhã, é todo o sentido desse fluxo. Mesmo valor para instruções ALTER TABLE em que o tipo de uma coluna estreita de VARCHAR(255) para VARCHAR(50).

Diff de duas versões de uma consulta analítica

Uma consulta de relatório que ontem retornou 12.400 linhas hoje retorna 8.900. Faça diff da consulta salva de ontem contra a de hoje e a mudança culpada aparece: um LEFT JOIN virou silenciosamente um INNER JOIN, ou um WHERE status <> 'cancelled' foi adicionado por alguém tentando limpar o dashboard. O diff de texto te leva à linha em segundos, onde ler ambas as consultas lado a lado no Slack levaria dez minutos.

Comparar SQL gerado por ORM entre versões da app

Depois de um upgrade do Hibernate ou SQLAlchemy, consultas que tinham três joins agora têm quatro com subconsultas extras, ou o binding de parâmetros mudou de ? para placeholders $1. Capture o SQL do log de consultas em cada versão da app (psql log_statement = all, slow log do MySQL ou sua ferramenta de APM) e faça diff. Os nomes de alias vão ser barulhentos (t1, t2, generatedAlias0), mas a mudança estrutural real costuma ser a única coisa que o diff destaca como edição de verdade.

Validar que uma refatoração de DDL preserva a intenção

Você renomeou user_orders para orders e dividiu uma coluna de blob JSON em tabelas normalizadas. Cole a saída de pg_dump --schema-only antes e depois da refatoração; o diff deixa óbvio se você preservou cada constraint, índice e default. A armadilha a ficar de olho é um NOT NULL que sumiu calado durante o rename, ou uma constraint UNIQUE que caiu porque ninguém a recolocou na tabela nova.

Verificar se o schema de staging bate com produção

Rode pg_dump --schema-only --no-owner contra staging e produção, e faça diff dos dois. As diferenças deveriam ser exatamente as migrações na fila para o próximo deploy. Qualquer outra coisa, um índice extra, um tipo de coluna diferente, uma tabela de teste esquecida, é sinal de drift de schema que vai morder no deploy real. Mesma abordagem com mysqldump --no-data para MySQL e SCRIPT TO para SQL Server, ou o export de schema do DataGrip em qualquer banco.

Revisar portabilidade de dialeto (Postgres para MySQL)

Portar uma consulta de PostgreSQL para MySQL ou vice-versa significa rastrear quais funções, tipos e cláusulas precisam mudar: SERIAL versus AUTO_INCREMENT, NOW() versus CURRENT_TIMESTAMP, RETURNING versus LAST_INSERT_ID(). Faça diff do original contra a versão portada e todas as substituições de dialeto aparecem. O diff não vai validar o SQL no dialeto de destino, então ainda passe pelo psql ou mysql para confirmar, mas a visão linha a linha te diz quais decisões revisar duas vezes.

Referência rápida de SQL

Uma cola curta para os casos limite de dialeto e parsing que este diff faz aparecer com mais frequência. Apoiada no padrão ISO SQL e nas docs dos principais fabricantes.

TopicWhat this tool does
Drift de dialetoPostgreSQL, MySQL, SQL Server, SQLite e Oracle estendem cada um o padrão ISO SQL com sintaxe própria. SERIAL, AUTO_INCREMENT, IDENTITY e GENERATED ALWAYS AS IDENTITY são quatro formas de escrever a mesma ideia.
Folding de caixa em identificadoresPostgreSQL dobra identificadores não entre aspas para minúsculas, então Users e users são a mesma tabela. MySQL depende de lower_case_table_names e do filesystem subjacente. SQL Server é case-insensitive por padrão mas respeita a collation. Use aspas em identificadores com "Users" (padrão), backticks (MySQL) ou colchetes (SQL Server) para preservar a caixa.
Caixa de palavras-chavePalavras-chave SQL são case-insensitive em todo lugar, então SELECT e select são idênticas para o parser. Convenção é maiúsculas para palavras-chave e minúsculas para identificadores; a maioria dos style guides e a spec ISO seguem isso. Caixa mista é válida e executa, mas ferramentas como sqlfluff e sqlfmt normalizam.
Estilos de comentárioDuas formas: -- comentário de linha (termina no fim da linha) e /* comentário de bloco */ (sem aninhamento em SQL padrão, embora alguns dialetos permitam). MySQL também suporta # para comentários de linha como extensão. O diff trata comentários como texto e mostra edições de comentário como qualquer outra mudança.
Separadores de instruçãoPonto e vírgula (;) termina uma instrução em SQL padrão. A maioria dos clientes exige isso entre instruções num script. Alguns clientes (SSMS) usam GO como separador de batch em vez disso, o que não faz parte da gramática SQL; é uma diretiva do cliente.
Strings com dollar-quoting (PostgreSQL)PostgreSQL suporta $tag$ ... $tag$ para literais de string para você não precisar escapar aspas simples por dentro, especialmente útil em corpos de função. $$ SELECT 'hello' $$ é válido e comum em blocos CREATE FUNCTION. Outros dialetos não parseiam essa sintaxe.
Placeholders de binding de parâmetroSem padrão. PostgreSQL e ORMs que miram nele usam $1, $2. JDBC, MySQL e ODBC usam ?. Placeholders nomeados :name são comuns em Oracle e em muitos templates de string de ORM. SQL gerado por ORM entre versões muitas vezes só difere no estilo de placeholder; formate ambos os lados antes do diff.
CodificaçãoUTF-8 é o default universal para arquivos SQL em 2026. Scripts antigos de origem Windows ainda podem estar salvos como UTF-16 LE com BOM, o que aparece como caractere fantasma na linha 1 num diff de texto. Se dois arquivos parecem idênticos mas o diff aponta uma mudança de um caractere no início, suspeite do BOM e salve de novo com UTF-8 explícito.

Diff SQL: perguntas frequentes

Em que isto difere de rodar EXPLAIN ANALYZE em ambas as consultas?

Camada diferente do stack. EXPLAIN ANALYZE te mostra o plano da consulta, o que o otimizador decidiu fazer dadas as estatísticas que ele tem. Esta ferramenta faz diff do texto da consulta, que é o que mudou no seu repo. Em geral você quer os dois: este diff para identificar a refatoração (um tipo de join mudou, um predicado se moveu), e depois EXPLAIN ANALYZE no psql ou no seu cliente para confirmar que o otimizador escolheu mesmo um plano sensato para o novo formato. Os dois são complementares, não substitutos.

O diff é consciente do dialeto (PostgreSQL vs MySQL vs SQL Server)?

Não. O diff trata a entrada como texto, então não parseia PostgreSQL, MySQL, SQL Server, SQLite ou Oracle de modo diferente e não sinaliza sintaxe incompatível entre dialetos. É de propósito: significa que você pode fazer diff entre dialetos, que é exatamente o que você quer ao portar uma consulta. Se você precisa de linting ciente de dialeto, passe o SQL pelo sqlfluff ou pelo parser do seu banco separadamente. Para o caso de revisão ("o que mudou nessa consulta"), o nível de texto é a granularidade certa.

A ferramenta formata SQL para mim?

Sim, o botão Format em cada painel reformata o SQL com indentação consistente, palavras-chave em maiúsculas e uma instrução por linha. É um formatador básico, não um substituto para sqlfmt ou sqlfluff: não reescreve joins implícitos para explícitos, e não impõe o style guide de um dialeto específico. A ideia é matar o ruído de formatação antes do diff, para que uma consulta formatada pelo DataGrip de um lado e uma escrita à mão do outro comparem limpas.

Ele normaliza a caixa das palavras-chave (SELECT vs select)?

O botão Format coloca palavras-chave em maiúsculas, que é a convenção na maioria dos style guides e no padrão ISO SQL. Se você não clica em Format, caixa mista aparece como diff porque o motor por baixo é baseado em caractere. Palavras-chave SQL são case-insensitive em todo banco, então select e SELECT executam idêntico. Caixa de identificadores é outra história e varia por banco; veja a referência rápida abaixo para como Postgres, MySQL e SQL Server divergem.

Como lidar com aliases gerados por ORM como t1, t2, generatedAlias0?

Saída de ORM é barulhenta por design: Hibernate gera generatedAlias0, generatedAlias1, e SQLAlchemy usa anon_1, anon_2. Se duas versões de ORM atribuem os mesmos aliases em ordem diferente, o diff de texto vai destacar cada troca de alias como mudança mesmo que a consulta seja estruturalmente idêntica. O conserto prático é formatar ambos os lados, ignorar diferenças que são só de alias (geralmente óbvias como pares de blocos vermelhos e verdes na mesma linha) e focar nas edições estruturais reais: um join novo, uma cláusula WHERE diferente, uma coluna removida.

Tem limites de tamanho no SQL que eu colo?

Limites suaves, não rígidos. O diff roda no seu navegador, então o teto é a memória do navegador e quanto você está disposto a esperar. Uma saída de pg_dump de 5.000 linhas roda diff bem abaixo de um segundo num laptop moderno. Um dump de 200.000 linhas pode levar vários segundos e bater em limites de memória em dispositivos mais modestos. Para dumps de banco assim de grandes, o fluxo certo é fazer diff só do schema primeiro (pg_dump --schema-only), e depois descer para tabelas específicas se você precisa de comparação em nível de dados.

Privacidade e como funciona

Seu SQL nunca sai do navegador. O formatador e o diff rodam ambos na sua máquina, localmente. Sem analytics da sua entrada, sem logs, sem ida e volta "prestativa" à nuvem, o que importa quando o SQL que você cola contém nomes reais de tabela, nomes reais de coluna, ou dados reais de produção numa linha de exemplo. A linguagem é documentada em ISO/IEC 9075, e as referências de dialeto são PostgreSQL, MySQL, SQL Server e SQLite.