Ursprunglig SQL
Ändrad SQL

SQL Diff: jämför två SQL-filer online

Klistra in, formatera och jämför två SQL-frågor eller schemafiler sida vid sida. Fungerar för PostgreSQL, MySQL, SQL Server, SQLite och Oracle.

Vad är SQL-diff-verktyget?

Ett gratis verktyg i webbläsaren för att jämföra två SQL-filer. Klistra in en gammal CREATE TABLE till vänster, den nya till höger, och ändringarna lyser tecken för tecken. Samma flöde för två versioner av en analysfråga, en sats genererad av ett ORM eller en pg_dump-utskrift. Inget lämnar din maskin.

Diffen arbetar på textnivå. Den parsar inte SQL till en AST och förstår inte semantisk likvärdighet: SELECT a, b och SELECT b, a ser olika ut för diffen, även om båda returnerar samma rader i en annan ordning. För 95 % av kodgranskningsuppgifter (schemamigrationer, frågerefaktoreringar, jämförelse av ORM-utskrift) är textdiff precis det du faktiskt vill ha, eftersom ordningen på kolumner och klausuler är en del av hur teamet läser ändringen.

Om du någonsin har försökt hitta den enda nya WHERE-klausulen i en 400-radig analysfråga som börjat returnera ett annat radantal, så är detta verktyget som tar dig dit på sekunder. För icke-SQL-text är vårt textdiff-verktyg rätt val. För ORM-resultatpayload i JSON hanterar JSON-diff omordning av objekt renare. För äldre DDL-exporter skrivna som XML-metadata passar XML-diff bättre.

Hur diffen faktiskt fungerar

Under huven körs diffen på teckennivå, sedan flyttar en semantisk pass markeringarna så att de landar på identifierare, nyckelord och klausulgränser i stället för slumpmässig interpunktion. Tillägg syns i grönt till höger, borttaganden i rött till vänster. Varje panel har en Format-knapp som ombryter SQL med konsekvent indrag och en sats per rad, vilket dödar det mesta formatbruset före jämförelsen.

SQL är en familj av dialekter, inte ett enda språk. ISO/IEC 9075-standarden definierar en kärngrammatik, men varje databas utökar den: PostgreSQL har dollar-citerade strängar och RETURNING, MySQL har backtick-identifierare och ON DUPLICATE KEY UPDATE, SQL Server använder TOP och identifierare i hakparenteser, SQLite tolererar nästan vad som helst, och Oracle har ROWNUM och CONNECT BY. Att diffa mellan dialekter är OK; verktyget varnar inte för att ett utdrag är ogiltigt i någon av dem.

Det andra att veta: att jämföra en frågas text är inte samma sak som att jämföra dess planer. Två satser med identisk text kan producera mycket olika planer med olika statistik, och två kosmetiskt olika satser kan producera identisk plan. För planjämförelse är de rätta verktygen EXPLAIN ANALYZE i psql eller motsvarande i din databasklient (DataGrip, DBeaver, SSMS). För textrefaktoreringsgranskning är diffen vad du vill ha. Bakgrundsläsning om språket självt på Wikipedia.

Så jämför du SQL i tre steg

Två textpaneler, en diff. Ingen registrering, ingen uppladdning, ingen serverrundtripp.

  1. 1

    Klistra in eller ladda upp din SQL

    Klistra in den gamla SQL till vänster, den nya till höger. Eller klicka på Ladda upp på endera sidan för att läsa in en .sql-, .ddl- eller .psql-fil direkt. Sample-knappen fyller båda panelerna med ett litet orders-schemaexempel om du vill se verktyget i drift först.

  2. 2

    Formatera båda sidor för en rättvis jämförelse

    Klicka på Format på varje panel för att ombryta SQL med konsekvent indrag, en sats per rad och nyckelord i versaler. Detta dödar bruset från en DataGrip-formaterad fråga på ena sidan och en handskriven på den andra, så diffen markerar verkliga schema- och klausulförändringar i stället för whitespace- och versalskillnader.

  3. 3

    Läs diffen

    Borttaganden visas med röd markering till vänster, tillägg med grön markering till höger. Skrolla en sida och den andra följer med. Ändringsräknarna i varje rubrik talar om hur många distinkta redigeringar diffen hittade över kolumner, joins, predikat och DDL-element.

När SQL-diff är rätt verktyg

Granska en schemamigration innan den körs

En migrations-PR lägger till tre kolumner och justerar två index. Klistra in den tidigare CREATE TABLE mot den nya och tilläggen sticker ut: en kolumn currency CHAR(3) NOT NULL har lagts till utan DEFAULT, vilket kommer att fela på alla befintliga rader. Att fånga det innan migrationen körs mot prod, i stället för efter att deploylarmet går klockan 2 på natten, är hela poängen med detta arbetsflöde. Samma värde för ALTER TABLE-satser där en kolumntyp smalnar från VARCHAR(255) till VARCHAR(50).

Diff på två versioner av en analysfråga

En rapportfråga som igår returnerade 12 400 rader returnerar idag 8 900. Diffa gårdagens sparade fråga mot dagens och den skyldiga ändringen kommer fram: en LEFT JOIN har tyst blivit en INNER JOIN, eller en WHERE status <> 'cancelled' har lagts till av någon som ville städa dashboarden. Textdiffen tar dig till raden på sekunder, medan att läsa båda frågorna sida vid sida i Slack skulle ta tio minuter.

Jämföra ORM-genererad SQL mellan app-versioner

Efter en uppgradering av Hibernate eller SQLAlchemy är frågor som var tre joins nu fyra med extra subqueries, eller parameterbindningen har gått från ? till $1-platshållare. Fånga SQL från frågeloggen på varje appversion (psql log_statement = all, MySQL slow log eller ditt APM-verktyg) och diffa dem. Aliasnamnen blir bullriga (t1, t2, generatedAlias0), men den verkliga strukturella förändringen är oftast det enda diffen markerar som en riktig redigering.

Validera att en DDL-refaktorering bevarar avsikten

Du har döpt om user_orders till orders och delat upp en JSON-blob-kolumn i normaliserade tabeller. Klistra in pg_dump --schema-only-utskriften före och efter refaktoreringen; diffen gör det uppenbart om du bevarat varje constraint, index och default. Fällan att hålla koll på är ett NOT NULL som tyst försvann under namnbytet, eller ett UNIQUE-constraint som föll bort eftersom ingen lade till det igen på den nya tabellen.

Kontrollera att stagings schema matchar prod

Kör pg_dump --schema-only --no-owner mot staging och prod, och diffa de två. Skillnaderna ska vara exakt de migrationer som står i kö för nästa deploy. Allt annat, ett extra index, en annan kolumntyp, en bortglömd testtabell, är ett tecken på schemadrift som biter under den faktiska deployen. Samma ansats med mysqldump --no-data för MySQL och SCRIPT TO för SQL Server, eller DataGrips schemaexport över valfri databas.

Granska dialektportering (Postgres till MySQL)

Att portera en fråga från PostgreSQL till MySQL eller tvärtom innebär att hålla koll på vilka funktioner, typer och klausuler som behöver ändras: SERIAL kontra AUTO_INCREMENT, NOW() kontra CURRENT_TIMESTAMP, RETURNING kontra LAST_INSERT_ID(). Diffa originalet mot den porterade versionen och alla dialektsubstitutioner kommer fram. Diffen kommer inte att validera SQL i måldialekten, så kör den ändå genom psql eller mysql för att bekräfta, men rad-för-rad-vyn berättar vilka beslut du behöver dubbelkolla.

SQL snabbreferens

Ett kort fusklapp över de dialekt- och parsing-randfall som denna diff oftast lyfter upp till ytan. Förankrat i ISO SQL-standarden och de stora leverantörernas dokumentation.

TopicWhat this tool does
DialektdriftPostgreSQL, MySQL, SQL Server, SQLite och Oracle utökar var och en ISO SQL-standarden med egen syntax. SERIAL, AUTO_INCREMENT, IDENTITY och GENERATED ALWAYS AS IDENTITY är fyra sätt att skriva samma idé.
Identifierar-versalvikningPostgreSQL viker ociterade identifierare till gemener, så Users och users är samma tabell. MySQL beror på lower_case_table_names och underliggande filsystem. SQL Server är versalokänslig som standard men respekterar collationen. Citera identifierare med "Users" (standard), backticks (MySQL) eller hakparenteser (SQL Server) för att bevara versaler.
Versaler för nyckelordSQL-nyckelord är versalokänsliga överallt, så SELECT och select är identiska för parsern. Konventionen är versaler för nyckelord och gemener för identifierare; de flesta stilguider och ISO-specen följer den. Blandade versaler är giltiga och körs, men verktyg som sqlfluff och sqlfmt normaliserar dem.
KommentarsstilarTvå former: -- radkommentar (slutar vid radslut) och /* blockkommentar */ (ingen kapsling i standard-SQL, även om vissa dialekter tillåter det). MySQL stöder också # för radkommentarer som tillägg. Diffen behandlar kommentarer som text och visar kommentarredigeringar som vilken annan ändring som helst.
SatsavskiljareSemikolon (;) avslutar en sats i standard-SQL. De flesta klienter kräver det mellan satser i ett skript. Vissa klienter (SSMS) använder i stället GO som batchavskiljare, vilket inte är en del av SQL-grammatiken; det är ett klientdirektiv.
Dollar-citerade strängar (PostgreSQL)PostgreSQL stöder $tag$ ... $tag$ för stränglitterater så att du inte behöver escape-a enkla citationstecken inuti, särskilt användbart för funktionskroppar. $$ SELECT 'hello' $$ är giltigt och vanligt i CREATE FUNCTION-block. Andra dialekter parsar inte denna syntax.
ParameterbindningsplatshållareIngen standard. PostgreSQL och ORM:er som siktar på det använder $1, $2. JDBC, MySQL och ODBC använder ?. Namngivna platshållare :name är vanliga i Oracle och i många ORM-strängmallar. ORM-genererad SQL skiljer sig ofta mellan versioner bara i platshållarstil; formatera båda sidor före diff.
KodningUTF-8 är den universella standarden för SQL-filer 2026. Äldre skript med Windows-ursprung kan fortfarande vara sparade som UTF-16 LE med BOM, vilket dyker upp som ett spöktecken på rad 1 i en textdiff. Om två filer ser identiska ut men diffen flaggar en enteckensändring i början, misstänk BOM:en och spara om med explicit UTF-8.

SQL-diff: vanliga frågor

Hur skiljer sig detta från att köra EXPLAIN ANALYZE på båda frågorna?

Annat lager i stacken. EXPLAIN ANALYZE visar dig frågans plan, det optimeraren bestämde sig för att göra givet den statistik den har. Det här verktyget diffar frågans text, det som ändrats i ditt repo. Du vill oftast ha båda: den här diffen för att hitta refaktoreringen (en jointyp ändrades, ett predikat flyttades), och sedan EXPLAIN ANALYZE i psql eller din klient för att bekräfta att optimeraren faktiskt valde en vettig plan för den nya formen. De två kompletterar varandra, de ersätter inte varandra.

Är diffen dialektsmedveten (PostgreSQL vs MySQL vs SQL Server)?

Nej. Diffen behandlar indata som text, så den parsar inte PostgreSQL, MySQL, SQL Server, SQLite eller Oracle olika och flaggar inte dialektinkompatibel syntax. Det är avsiktligt: det betyder att du kan diffa över dialekter, vilket är precis vad du vill när du porterar en fråga. Behöver du dialektsmedveten linting kör du SQL genom sqlfluff eller din databas parser separat. För granskningsfallet ("vad ändrades i den här frågan") är textnivå rätt granularitet.

Formaterar verktyget SQL åt mig?

Ja, Format-knappen på varje panel ombryter SQL med konsekvent indrag, nyckelord i versaler och en sats per rad. Det är en grundläggande formatterare, inte en ersättare för sqlfmt eller sqlfluff: den skriver inte om implicita joins till explicita, och den tvingar inte fram någon viss dialekts stilguide. Poängen är att döda formatbruset före diffen, så att en DataGrip-formaterad fråga på ena sidan och en handskriven på den andra jämförs rent.

Normaliserar den nyckelordens versaler (SELECT vs select)?

Format-knappen sätter nyckelord i versaler, vilket är konventionen i de flesta stilguider och i ISO SQL-standarden. Klickar du inte på Format dyker blandade versaler upp som diff eftersom motorn under är teckenbaserad. SQL-nyckelord är versalokänsliga i alla databaser, så select och SELECT körs identiskt. Identifierar-versaler är en annan fråga och varierar mellan databaser; se snabbreferensen nedan för hur Postgres, MySQL och SQL Server skiljer sig åt.

Hur hanterar jag ORM-genererade alias som t1, t2, generatedAlias0?

ORM-utskrift är bullrig till sin natur: Hibernate genererar generatedAlias0, generatedAlias1, och SQLAlchemy använder anon_1, anon_2. Om två ORM-versioner tilldelar samma alias i olika ordning kommer textdiffen att markera varje aliasbyte som ändring, även om frågan är strukturellt identisk. Den praktiska lösningen är att formatera båda sidor, ignorera alias-bara-skillnader (oftast tydliga som parade röda och gröna block på samma rad) och fokusera på de verkliga strukturella redigeringarna: en ny join, en annan WHERE-klausul, en borttagen kolumn.

Finns det storleksgränser på SQL jag klistrar in?

Mjuka gränser, inte hårda. Diffen körs i din webbläsare, så övre gränsen är webbläsarens minne och hur länge du är beredd att vänta. En pg_dump-utskrift på 5 000 rader diffas på betydligt under en sekund på en modern laptop. En dump på 200 000 rader kan ta flera sekunder och nudda minnesgränser på svagare enheter. För så stora databasdumpar är rätt flöde att först diffa enbart schemat (pg_dump --schema-only) och sedan borra ner i specifika tabeller om du behöver jämföra på datanivå.

Integritet och hur det fungerar

Din SQL lämnar aldrig din webbläsare. Formatteraren och diffen körs båda på din maskin, lokalt. Ingen analytics på din inmatning, inga loggar, ingen "hjälpsam" molnrundtripp, vilket spelar roll när SQL du klistrar in innehåller riktiga tabellnamn, riktiga kolumnnamn eller riktiga produktionsdata på en exempelrad. Språket är dokumenterat i ISO/IEC 9075, och dialektreferenserna är PostgreSQL, MySQL, SQL Server och SQLite.