Diff SQL : Comparez Deux Fichiers SQL en Ligne
Collez, formatez et comparez deux requêtes SQL ou fichiers de schéma côte à côte. Fonctionne avec PostgreSQL, MySQL, SQL Server, SQLite et Oracle.
Qu'est-ce que l'outil de diff SQL ?
Un outil gratuit dans le navigateur pour comparer deux fichiers SQL. Collez un ancien CREATE TABLE à gauche, le nouveau à droite, et les changements s'éclairent caractère par caractère. Même flux pour deux versions d'une requête analytique, une instruction émise par un ORM, ou la sortie d'un pg_dump. Rien ne quitte votre machine.
Le diff fonctionne au niveau du texte. Il ne parse pas le SQL en AST et il ne comprend pas l'équivalence sémantique : SELECT a, b et SELECT b, a sont vus comme différents par le diff même si tous deux renvoient les mêmes lignes dans un autre ordre. Pour 95 % des tâches de revue de code (migrations de schéma, refactor de requêtes, comparaison de sortie ORM) le diff de texte est ce que vous voulez vraiment, parce que l'ordre des colonnes et des clauses fait partie de la façon dont l'équipe lit le changement.
Si vous avez déjà essayé de trouver l'unique nouvelle clause WHERE dans une requête analytique de 400 lignes qui s'est mise à renvoyer un nombre de lignes différent, c'est l'outil qui vous y mène en quelques secondes. Pour de la prose hors SQL, notre outil de diff de texte est le bon choix. Pour des payloads de résultats ORM en JSON, JSON diff gère le réordonnancement d'objets plus proprement. Pour des exports DDL anciens écrits comme métadonnées XML, XML diff convient mieux.
Comment le diff fonctionne réellement
Sous le capot, le diff tourne au niveau du caractère, puis une passe sémantique décale les surlignages pour qu'ils tombent sur des identifiants, des mots-clés et des frontières de clauses plutôt que sur de la ponctuation aléatoire. Les insertions s'affichent en vert à droite, les suppressions en rouge à gauche. Chaque panneau a un bouton Format qui reformate le SQL avec une indentation cohérente et une instruction par ligne, ce qui tue la majorité du bruit de mise en forme avant la comparaison.
SQL est une famille de dialectes, pas un langage unique. La norme ISO/IEC 9075 définit une grammaire de base, mais chaque base de données l'étend : PostgreSQL a les chaînes en dollar-quoting et RETURNING, MySQL a les identifiants entre backticks et ON DUPLICATE KEY UPDATE, SQL Server utilise TOP et les identifiants entre crochets, SQLite tolère presque tout, et Oracle a ROWNUM et CONNECT BY. Faire un diff entre dialectes ne pose pas de problème ; l'outil ne vous avertira pas qu'un fragment est invalide dans l'un d'eux.
L'autre point à connaître : comparer le texte d'une requête n'est pas la même chose que comparer ses plans. Deux instructions au texte identique peuvent produire des plans très différents avec des statistiques différentes, et deux instructions cosmétiquement différentes peuvent produire le même plan. Pour comparer les plans, les bons outils sont EXPLAIN ANALYZE dans psql ou l'équivalent dans votre client de base de données (DataGrip, DBeaver, SSMS). Pour la revue de refactor textuel, le diff est ce qu'il vous faut. Lecture de fond sur le langage lui-même sur Wikipedia.
Comment comparer du SQL en trois étapes
Deux panneaux de texte, un diff. Pas d'inscription, pas d'upload, pas d'aller-retour serveur.
- 1
Collez ou téléversez votre SQL
Collez l'ancien SQL à gauche, le nouveau à droite. Ou cliquez sur Téléverser de l'un ou l'autre côté pour charger directement un fichier .sql, .ddl ou .psql. Le bouton Exemple remplit les deux panneaux avec un petit schéma orders si vous voulez d'abord voir l'outil en action.
- 2
Formatez les deux côtés pour une comparaison juste
Cliquez sur Format sur chaque panneau pour reformater le SQL avec une indentation cohérente, une instruction par ligne et des mots-clés en majuscules. Cela tue le bruit d'une requête formatée par DataGrip d'un côté et tapée à la main de l'autre, pour que le diff mette en évidence les vrais changements de schéma et de clauses au lieu des différences d'espaces et de casse.
- 3
Lisez le diff
Les suppressions apparaissent surlignées en rouge à gauche, les insertions en vert à droite. Faites défiler un côté et l'autre suit. Les compteurs de changements dans chaque en-tête vous disent combien d'éditions distinctes le diff a trouvées entre colonnes, jointures, prédicats et éléments DDL.
Quand le diff SQL est le bon outil
Revoir une migration de schéma avant application
Une PR de migration ajoute trois colonnes et ajuste deux index. Collez l'ancien CREATE TABLE contre le nouveau et les ajouts ressortent : une colonne currency CHAR(3) NOT NULL a été ajoutée sans DEFAULT, ce qui échouera sur toute ligne existante. Attraper ça avant que la migration ne tourne contre la prod, plutôt qu'après que l'alarme de déploiement se déclenche à 2 h du matin, c'est tout l'intérêt de ce flux. Même valeur pour des instructions ALTER TABLE où le type d'une colonne se rétrécit de VARCHAR(255) à VARCHAR(50).
Diff de deux versions d'une requête analytique
Une requête de reporting qui renvoyait 12 400 lignes hier en renvoie 8 900 aujourd'hui. Faites un diff de la requête sauvegardée d'hier contre celle d'aujourd'hui et le changement coupable apparaît : un LEFT JOIN est devenu silencieusement un INNER JOIN, ou un WHERE status <> 'cancelled' a été ajouté par quelqu'un qui essayait de nettoyer le tableau de bord. Le diff de texte vous emmène à la ligne en quelques secondes, là où lire les deux requêtes côte à côte dans Slack prendrait dix minutes.
Comparer du SQL généré par ORM entre versions de l'application
Après une mise à jour de Hibernate ou SQLAlchemy, des requêtes qui étaient à trois jointures sont passées à quatre avec des sous-requêtes en plus, ou le binding de paramètres est passé de ? aux placeholders $1. Capturez le SQL depuis votre log de requêtes sur chaque version de l'app (psql log_statement = all, slow log MySQL ou votre outil APM) et faites le diff. Les noms d'alias seront bruyants (t1, t2, generatedAlias0), mais le vrai changement structurel est généralement la seule chose que le diff signale comme édition réelle.
Vérifier qu'un refactor DDL préserve l'intention
Vous avez renommé user_orders en orders et éclaté une colonne JSON en tables normalisées. Collez la sortie de pg_dump --schema-only avant et après le refactor ; le diff rend évident si vous avez préservé chaque contrainte, index et default. Le piège à surveiller est un NOT NULL qui a discrètement disparu pendant le rename, ou une contrainte UNIQUE tombée parce que personne ne l'a re-ajoutée sur la nouvelle table.
Vérifier que le schéma de staging correspond à la prod
Lancez pg_dump --schema-only --no-owner contre staging et prod, puis faites le diff des deux. Les différences devraient être exactement les migrations en file pour le prochain déploiement. Toute autre chose, un index en plus, un type de colonne différent, une table de test oubliée, est un signe de drift de schéma qui mordra pendant le déploiement réel. Même approche avec mysqldump --no-data pour MySQL et SCRIPT TO pour SQL Server, ou l'export de schéma de DataGrip sur n'importe quelle base.
Revoir un portage de dialecte (Postgres vers MySQL)
Porter une requête de PostgreSQL à MySQL ou inversement signifie suivre quelles fonctions, types et clauses doivent changer : SERIAL versus AUTO_INCREMENT, NOW() versus CURRENT_TIMESTAMP, RETURNING versus LAST_INSERT_ID(). Faites un diff de l'original contre la version portée et toutes les substitutions de dialecte apparaissent. Le diff ne validera pas le SQL sur le dialecte cible, donc passez-le quand même par psql ou mysql pour confirmer, mais la vue ligne par ligne vous dit quelles décisions revérifier.
Référence rapide SQL
Une courte fiche des cas limites de dialecte et de parsing que ce diff fait remonter le plus souvent. Adossée à la norme ISO SQL et aux docs des principaux éditeurs.
| Topic | What this tool does |
|---|
| Drift de dialecte | PostgreSQL, MySQL, SQL Server, SQLite et Oracle étendent chacun la norme ISO SQL avec leur propre syntaxe. SERIAL, AUTO_INCREMENT, IDENTITY et GENERATED ALWAYS AS IDENTITY sont quatre façons d'écrire la même idée. |
|---|
| Pliage de casse des identifiants | PostgreSQL plie les identifiants non quotés en minuscules, donc Users et users sont la même table. MySQL dépend de lower_case_table_names et du système de fichiers sous-jacent. SQL Server est insensible à la casse par défaut mais respecte la collation. Quotez les identifiants avec "Users" (standard), des backticks (MySQL) ou des crochets (SQL Server) pour préserver la casse. |
|---|
| Casse des mots-clés | Les mots-clés SQL sont insensibles à la casse partout, donc SELECT et select sont identiques pour le parser. La convention est majuscules pour les mots-clés et minuscules pour les identifiants ; la plupart des guides de style et la spec ISO la suivent. La casse mixte est valide et s'exécute, mais des outils comme sqlfluff et sqlfmt la normalisent. |
|---|
| Styles de commentaires | Deux formes : -- commentaire de ligne (se termine à la fin de la ligne) et /* commentaire de bloc */ (pas d'imbrication en SQL standard, bien que certains dialectes l'autorisent). MySQL prend aussi en charge # pour les commentaires de ligne en extension. Le diff traite les commentaires comme du texte et affichera les éditions de commentaires comme tout autre changement. |
|---|
| Séparateurs d'instructions | Le point-virgule (;) termine une instruction en SQL standard. La plupart des clients l'exigent entre instructions dans un script. Certains clients (SSMS) utilisent GO comme séparateur de batch à la place, ce qui ne fait pas partie de la grammaire SQL ; c'est une directive client. |
|---|
| Chaînes en dollar-quoting (PostgreSQL) | PostgreSQL prend en charge $tag$ ... $tag$ pour les littéraux de chaîne afin que vous n'ayez pas à échapper les apostrophes à l'intérieur, particulièrement utile pour les corps de fonctions. $$ SELECT 'hello' $$ est valide et courant dans les blocs CREATE FUNCTION. Les autres dialectes ne parsent pas cette syntaxe. |
|---|
| Placeholders de binding de paramètres | Pas de standard. PostgreSQL et les ORM qui le ciblent utilisent $1, $2. JDBC, MySQL et ODBC utilisent ?. Les placeholders nommés :name sont courants dans Oracle et de nombreux templates de chaînes ORM. Le SQL généré par ORM diffère souvent uniquement par le style de placeholder entre versions ; formatez les deux côtés avant de faire un diff. |
|---|
| Encodage | UTF-8 est le défaut universel pour les fichiers SQL en 2026. Des scripts plus anciens d'origine Windows peuvent encore être enregistrés en UTF-16 LE avec un BOM, ce qui apparaît comme un caractère fantôme à la ligne 1 dans un diff de texte. Si deux fichiers semblent identiques mais que le diff signale un changement d'un caractère au début, suspectez le BOM et ré-enregistrez en UTF-8 explicite. |
|---|
Diff SQL : foire aux questions
En quoi est-ce différent de lancer EXPLAIN ANALYZE sur les deux requêtes ?
Couche différente de la stack. EXPLAIN ANALYZE vous montre le plan de la requête, ce que l'optimiseur a décidé de faire compte tenu des statistiques dont il dispose. Cet outil fait un diff du texte de la requête, ce qui a changé dans votre repo. Vous voulez généralement les deux : ce diff pour repérer le refactor (un type de jointure a changé, un prédicat a bougé), puis EXPLAIN ANALYZE dans psql ou votre client pour confirmer que l'optimiseur a bien choisi un plan sensé pour la nouvelle forme. Les deux sont complémentaires, pas substituables.
Le diff est-il conscient du dialecte (PostgreSQL vs MySQL vs SQL Server) ?
Non. Le diff traite l'entrée comme du texte, donc il ne parse pas PostgreSQL, MySQL, SQL Server, SQLite ou Oracle différemment et il ne signale pas la syntaxe incompatible entre dialectes. C'est intentionnel : ça veut dire que vous pouvez faire un diff entre dialectes, ce qui est exactement ce que vous voulez en portant une requête. Si vous avez besoin d'un linting conscient du dialecte, passez le SQL par sqlfluff ou par le parser de votre base séparément. Pour le cas d'usage de revue (« qu'est-ce qui a changé dans cette requête »), le niveau texte est la bonne granularité.
L'outil formate-t-il le SQL pour moi ?
Oui, le bouton Format sur chaque panneau reformate le SQL avec une indentation cohérente, des mots-clés en majuscules et une instruction par ligne. C'est un formateur basique, pas un remplaçant de sqlfmt ou sqlfluff : il ne réécrit pas les jointures implicites en explicites, et il n'impose pas le guide de style d'un dialecte particulier. Le but est de tuer le bruit de mise en forme avant le diff, pour qu'une requête formatée par DataGrip d'un côté et tapée à la main de l'autre se comparent proprement.
Normalise-t-il la casse des mots-clés (SELECT vs select) ?
Le bouton Format met les mots-clés en majuscules, ce qui est la convention dans la plupart des guides de style et dans la norme ISO SQL. Si vous ne cliquez pas sur Format, la casse mixte apparaît comme un diff parce que le moteur sous-jacent fonctionne au caractère. Les mots-clés SQL sont insensibles à la casse partout, donc select et SELECT s'exécutent de façon identique. La casse des identifiants est une autre question et varie selon la base ; voyez la référence rapide ci-dessous pour les différences entre Postgres, MySQL et SQL Server.
Comment gérer les alias générés par ORM comme t1, t2, generatedAlias0 ?
La sortie d'ORM est bruyante par construction : Hibernate génère generatedAlias0, generatedAlias1, et SQLAlchemy utilise anon_1, anon_2. Si deux versions d'ORM assignent les mêmes alias dans un ordre différent, le diff de texte signalera chaque échange d'alias comme un changement même si la requête est structurellement identique. La parade pratique est de formater les deux côtés, d'ignorer les différences purement d'alias (elles sont généralement évidentes sous forme de blocs rouges et verts appariés sur la même ligne) et de se concentrer sur les vraies éditions structurelles : une nouvelle jointure, une clause WHERE différente, une colonne supprimée.
Y a-t-il des limites de taille sur le SQL collé ?
Limites souples, pas dures. Le diff tourne dans votre navigateur, donc le plafond est la mémoire du navigateur et combien de temps vous êtes prêt à attendre. Une sortie pg_dump de 5 000 lignes se diffe en bien moins d'une seconde sur un portable moderne. Un dump de 200 000 lignes peut prendre plusieurs secondes et frôler les limites de mémoire sur des appareils plus modestes. Pour des dumps de base aussi gros, le bon flux est de faire un diff schema-only d'abord (pg_dump --schema-only), puis de descendre dans des tables précises si vous avez besoin de comparer au niveau données.
Confidentialité et fonctionnement
Votre SQL ne quitte jamais votre navigateur. Le formateur et le diff tournent tous les deux sur votre machine, en local. Pas d'analytique sur vos entrées, pas de logs, pas d'aller-retour cloud « pour aider », ce qui compte quand le SQL que vous collez contient de vrais noms de tables, de vraies colonnes ou de vraies données de production dans une ligne d'exemple. Le langage est documenté dans ISO/IEC 9075, et les références de dialecte sont PostgreSQL, MySQL, SQL Server et SQLite.