SQL originale
SQL modificato

Diff SQL: Confronta Due File SQL Online

Incolla, formatta e confronta due query SQL o file di schema affiancati. Funziona con PostgreSQL, MySQL, SQL Server, SQLite e Oracle.

Cos'è lo strumento di diff SQL?

Uno strumento gratuito nel browser per confrontare due file SQL. Incolla un vecchio CREATE TABLE a sinistra, quello nuovo a destra, e le modifiche si accendono carattere per carattere. Stesso flusso per due versioni di una query analitica, un'istruzione emessa da un ORM, o l'output di un pg_dump. Niente lascia la tua macchina.

Il diff è a livello testo. Non parsifica l'SQL in un AST e non capisce equivalenza semantica: SELECT a, b e SELECT b, a appaiono diversi al diff anche se entrambi restituiscono le stesse righe in un altro ordine. Per il 95% dei task di code review (migrazioni di schema, refactoring di query, confronto di output ORM) il diff testuale è quello che serve davvero, perché l'ordine di colonne e clausole fa parte di come il team legge il cambiamento.

Se hai mai provato a trovare l'unica nuova clausola WHERE in una query analitica di 400 righe che ha iniziato a restituire un conteggio righe diverso, questo è lo strumento che ti porta lì in pochi secondi. Per prosa non SQL, il nostro strumento di diff testuale è la scelta giusta. Per payload di risultati ORM in JSON, JSON diff gestisce il riordino degli oggetti in modo più pulito. Per export DDL legacy scritti come metadati XML, XML diff calza meglio.

Come funziona davvero il diff

Sotto il cofano il diff gira a livello di carattere, e poi una passata semantica sposta gli evidenziatori in modo che cadano su identificatori, parole chiave e confini di clausola invece che su punteggiatura casuale. Le inserzioni appaiono in verde a destra, le rimozioni in rosso a sinistra. Ogni riquadro ha un pulsante Format che riformatta l'SQL con indentazione coerente e una istruzione per riga, il che elimina la maggior parte del rumore di formattazione prima del confronto.

SQL è una famiglia di dialetti, non un singolo linguaggio. Lo standard ISO/IEC 9075 definisce una grammatica di base, ma ogni database la estende: PostgreSQL ha stringhe in dollar-quoting e RETURNING, MySQL ha identificatori con backtick e ON DUPLICATE KEY UPDATE, SQL Server usa TOP e identificatori tra parentesi quadre, SQLite tollera quasi qualsiasi cosa, e Oracle ha ROWNUM e CONNECT BY. Fare diff tra dialetti va bene; lo strumento non ti avviserà che uno snippet è invalido in uno di essi.

L'altra cosa da sapere: confrontare il testo di una query non è la stessa cosa che confrontare i piani. Due istruzioni con testo identico possono produrre piani molto diversi con statistiche diverse, e due istruzioni cosmeticamente diverse possono produrre lo stesso piano. Per il confronto di piani, gli strumenti giusti sono EXPLAIN ANALYZE in psql o l'equivalente nel tuo client di database (DataGrip, DBeaver, SSMS). Per la review di refactoring testuale, il diff è ciò che vuoi. Letture di approfondimento sul linguaggio in sé su Wikipedia.

Come confrontare SQL in tre passi

Due riquadri di testo, un diff. Niente registrazione, niente upload, niente andata e ritorno al server.

  1. 1

    Incolla o carica il tuo SQL

    Incolla l'SQL vecchio a sinistra, quello nuovo a destra. Oppure clicca Carica su uno dei due lati per caricare direttamente un file .sql, .ddl o .psql. Il pulsante Esempio riempie entrambi i riquadri con un piccolo schema orders se vuoi vedere prima lo strumento in azione.

  2. 2

    Formatta entrambi i lati per un confronto equo

    Clicca Format su ogni riquadro per riformattare l'SQL con indentazione coerente, una istruzione per riga e parole chiave in maiuscolo. Questo elimina il rumore di una query formattata da DataGrip da un lato e una scritta a mano dall'altro, così il diff evidenzia veri cambiamenti di schema e di clausole invece di differenze di spazi e maiuscole/minuscole.

  3. 3

    Leggi il diff

    Le rimozioni appaiono evidenziate in rosso a sinistra, le inserzioni in verde a destra. Scorri un lato e l'altro segue. I contatori di modifiche in ogni intestazione ti dicono quante modifiche distinte il diff ha trovato tra colonne, join, predicati ed elementi DDL.

Quando il diff SQL è lo strumento giusto

Rivedere una migrazione di schema prima di applicarla

Una PR di migrazione aggiunge tre colonne e ritocca due indici. Incolla il CREATE TABLE precedente contro il nuovo e le aggiunte saltano fuori: una colonna currency CHAR(3) NOT NULL è stata aggiunta senza DEFAULT, il che fallirà su qualsiasi riga esistente. Beccare quello prima che la migrazione giri contro la prod, invece che dopo che l'allarme di deploy suona alle 2 di notte, è tutto il senso di questo flusso. Stesso valore per istruzioni ALTER TABLE in cui il tipo di una colonna si restringe da VARCHAR(255) a VARCHAR(50).

Diff di due versioni di una query analitica

Una query di reporting che ieri restituiva 12.400 righe oggi ne restituisce 8.900. Fai il diff della query salvata di ieri contro quella di oggi e il cambio colpevole emerge: un LEFT JOIN è diventato silenziosamente un INNER JOIN, oppure un WHERE status <> 'cancelled' è stato aggiunto da qualcuno che cercava di pulire la dashboard. Il diff testuale ti porta alla riga in pochi secondi, mentre leggere le due query affiancate in Slack ci metterebbe dieci minuti.

Confrontare SQL generato da ORM tra versioni dell'app

Dopo un upgrade di Hibernate o SQLAlchemy, query che erano a tre join ora sono a quattro con sottoquery in più, oppure il binding dei parametri è passato da ? ai placeholder $1. Cattura l'SQL dal tuo log delle query su ciascuna versione dell'app (psql log_statement = all, slow log di MySQL o il tuo strumento APM) e fanne il diff. I nomi degli alias saranno rumorosi (t1, t2, generatedAlias0), ma il vero cambiamento strutturale di solito è l'unica cosa che il diff evidenzia come modifica reale.

Verificare che un refactoring DDL preservi l'intento

Hai rinominato user_orders in orders e diviso una colonna blob JSON in tabelle normalizzate. Incolla l'output di pg_dump --schema-only prima e dopo il refactoring; il diff rende ovvio se hai conservato ogni constraint, indice e default. La trappola da cui guardarsi è un NOT NULL sparito in silenzio durante la rinomina, o una constraint UNIQUE caduta perché nessuno l'ha rimessa sulla nuova tabella.

Controllare che lo schema di staging coincida con la prod

Esegui pg_dump --schema-only --no-owner contro staging e prod, poi fai il diff dei due. Le differenze dovrebbero essere esattamente le migrazioni in coda per il prossimo deploy. Qualunque altra cosa, un indice in più, un tipo di colonna diverso, una tabella di test dimenticata, è un segno di drift di schema che morderà al deploy vero. Stesso approccio con mysqldump --no-data per MySQL e SCRIPT TO per SQL Server, oppure l'export di schema di DataGrip su qualsiasi database.

Rivedere il porting tra dialetti (Postgres a MySQL)

Portare una query da PostgreSQL a MySQL o viceversa significa tracciare quali funzioni, tipi e clausole devono cambiare: SERIAL contro AUTO_INCREMENT, NOW() contro CURRENT_TIMESTAMP, RETURNING contro LAST_INSERT_ID(). Fai il diff dell'originale contro la versione portata e tutte le sostituzioni di dialetto vengono fuori. Il diff non valida l'SQL sul dialetto di destinazione, quindi passalo comunque per psql o mysql per conferma, ma la vista riga per riga ti dice quali decisioni ricontrollare.

Riferimento rapido SQL

Un breve cheat sheet sui casi limite di dialetto e parsing che questo diff fa emergere più spesso. Ancorato allo standard ISO SQL e alla documentazione dei principali fornitori.

TopicWhat this tool does
Drift di dialettoPostgreSQL, MySQL, SQL Server, SQLite e Oracle estendono ciascuno lo standard ISO SQL con la propria sintassi. SERIAL, AUTO_INCREMENT, IDENTITY e GENERATED ALWAYS AS IDENTITY sono quattro modi di scrivere la stessa idea.
Folding di cassa degli identificatoriPostgreSQL piega gli identificatori non quotati in minuscolo, quindi Users e users sono la stessa tabella. MySQL dipende da lower_case_table_names e dal filesystem sottostante. SQL Server è case-insensitive di default ma rispetta la collation. Quota gli identificatori con "Users" (standard), backtick (MySQL) o parentesi quadre (SQL Server) per preservare la cassa.
Cassa delle parole chiaveLe parole chiave SQL sono case-insensitive ovunque, quindi SELECT e select sono identiche per il parser. La convenzione è maiuscolo per le parole chiave e minuscolo per gli identificatori; la maggior parte delle guide di stile e la spec ISO la seguono. La cassa mista è valida ed esegue, ma strumenti come sqlfluff e sqlfmt la normalizzano.
Stili di commentoDue forme: -- commento di riga (termina a fine riga) e /* commento di blocco */ (senza annidamento nello SQL standard, anche se alcuni dialetti lo permettono). MySQL supporta anche # per commenti di riga come estensione. Il diff tratta i commenti come testo e mostra le modifiche dei commenti come qualsiasi altro cambiamento.
Separatori di istruzioneIl punto e virgola (;) termina un'istruzione nello SQL standard. La maggior parte dei client lo richiede tra istruzioni in uno script. Alcuni client (SSMS) usano GO come separatore di batch invece, che non fa parte della grammatica SQL; è una direttiva del client.
Stringhe in dollar-quoting (PostgreSQL)PostgreSQL supporta $tag$ ... $tag$ per i letterali di stringa così non devi escapare gli apici dentro, particolarmente utile per i corpi delle funzioni. $$ SELECT 'hello' $$ è valido e comune nei blocchi CREATE FUNCTION. Altri dialetti non parsificano questa sintassi.
Placeholder di binding parametriNessuno standard. PostgreSQL e gli ORM che lo puntano usano $1, $2. JDBC, MySQL e ODBC usano ?. I placeholder nominati :name sono comuni in Oracle e in molti template di stringa di ORM. L'SQL generato da ORM tra versioni differisce spesso solo nello stile di placeholder; formatta entrambi i lati prima del diff.
CodificaUTF-8 è il default universale per i file SQL nel 2026. Script più vecchi di origine Windows possono ancora essere salvati come UTF-16 LE con BOM, che appare come carattere fantasma alla riga 1 in un diff testuale. Se due file sembrano identici ma il diff segnala una modifica di un carattere all'inizio, sospetta del BOM e risalva con UTF-8 esplicito.

Diff SQL: domande frequenti

In che modo è diverso da lanciare EXPLAIN ANALYZE su entrambe le query?

Strato diverso dello stack. EXPLAIN ANALYZE ti mostra il piano della query, ciò che l'ottimizzatore ha deciso di fare date le statistiche che ha. Questo strumento fa il diff del testo della query, ciò che è cambiato nel tuo repo. Di solito vuoi entrambi: questo diff per individuare il refactoring (è cambiato un tipo di join, un predicato si è spostato), poi EXPLAIN ANALYZE in psql o nel tuo client per confermare che l'ottimizzatore abbia effettivamente scelto un piano sensato per la nuova forma. I due sono complementari, non sostituti.

Il diff è consapevole del dialetto (PostgreSQL vs MySQL vs SQL Server)?

No. Il diff tratta l'input come testo, quindi non parsifica PostgreSQL, MySQL, SQL Server, SQLite o Oracle in modo diverso e non segnala sintassi incompatibili tra dialetti. È intenzionale: significa che puoi fare diff tra dialetti, che è esattamente quello che vuoi quando porti una query. Se ti serve linting consapevole del dialetto, passa l'SQL attraverso sqlfluff o il parser del tuo database separatamente. Per il caso d'uso di review ("cosa è cambiato in questa query"), il livello testuale è la granularità giusta.

Lo strumento formatta l'SQL al posto mio?

Sì, il pulsante Format su ogni riquadro riformatta l'SQL con indentazione coerente, parole chiave in maiuscolo e una istruzione per riga. È un formatter base, non un sostituto di sqlfmt o sqlfluff: non riscrive i join impliciti in espliciti, e non impone la guida di stile di un dialetto specifico. Il punto è eliminare il rumore di formattazione prima del diff, così una query formattata da DataGrip da un lato e una scritta a mano dall'altro si confrontano in modo pulito.

Normalizza la cassa delle parole chiave (SELECT vs select)?

Il pulsante Format mette le parole chiave in maiuscolo, che è la convenzione nella maggior parte delle guide di stile e nello standard ISO SQL. Se non clicchi Format, la cassa mista compare come diff perché il motore sottostante è basato sui caratteri. Le parole chiave SQL sono case-insensitive in ogni database, quindi select e SELECT eseguono in modo identico. La cassa degli identificatori è un'altra questione e varia per database; vedi il riferimento rapido sotto per come differiscono Postgres, MySQL e SQL Server.

Come gestisco gli alias generati dall'ORM tipo t1, t2, generatedAlias0?

L'output ORM è rumoroso per design: Hibernate genera generatedAlias0, generatedAlias1, e SQLAlchemy usa anon_1, anon_2. Se due versioni di ORM assegnano gli stessi alias in ordine diverso, il diff testuale evidenzierà ogni scambio di alias come modifica anche se la query è strutturalmente identica. Il rimedio pratico è formattare entrambi i lati, ignorare le differenze di soli alias (di solito sono ovvie come coppie di blocchi rossi e verdi sulla stessa riga), e concentrarsi sulle modifiche strutturali reali: un nuovo join, una clausola WHERE diversa, una colonna rimossa.

Ci sono limiti di dimensione sull'SQL che incollo?

Limiti morbidi, non rigidi. Il diff gira nel tuo browser, quindi il tetto è la memoria del browser e quanto sei disposto ad aspettare. Un output di pg_dump da 5.000 righe fa diff in molto meno di un secondo su un laptop moderno. Un dump da 200.000 righe può richiedere diversi secondi e arrivare ai limiti di memoria su dispositivi più modesti. Per dump di database così grandi, il flusso giusto è fare prima il diff solo dello schema (pg_dump --schema-only), poi scendere su tabelle specifiche se serve un confronto a livello dati.

Privacy e come funziona

Il tuo SQL non lascia mai il browser. Il formatter e il diff girano entrambi sulla tua macchina, in locale. Niente analytics sul tuo input, niente log, nessun andata e ritorno cloud "servizievole", cosa che conta quando l'SQL che incolli contiene nomi reali di tabella, nomi reali di colonna, o dati reali di produzione in una riga di esempio. Il linguaggio è documentato in ISO/IEC 9075, e i riferimenti di dialetto sono PostgreSQL, MySQL, SQL Server e SQLite.