File types · Explainer

The SQL file (.sql)

A SQL file is a plain-text script of database commands: statements that create tables, add or change data and run queries, one after another. This guide explains what's inside one, how to run it against PostgreSQL, MySQL, SQLite or SQL Server, why a script for one database often fails on another, and has free sample SQL files to download for testing.

At a glance

Full name
SQL script; SQL stands for Structured Query Language
Extensions
.sql
MIME type
application/sql (RFC 6922, 2013); text/x-sql is also seen
Kind
Plain text: statements a database runs in order
Encoding
Not stored in the file; UTF-8 is the usual choice, but the tool running it decides how to read it
Standard
ISO/IEC 9075 (latest edition 2023); every database adds its own dialect
First released
The language began at IBM in 1974 as SEQUEL; first standardised by ANSI in 1986 and ISO in 1987
Runs with
psql, mysql, sqlite3, sqlcmd, or a GUI such as DBeaver, pgAdmin, MySQL Workbench or SSMS
Statement separator
; at the end of each statement; SQL Server tools also split batches on GO lines
Comments
-- line and /* block */; MySQL also accepts #
Magic number
None

The basics

What is a SQL file?

A .sql file holds SQL statements as plain text. Nothing happens until a database client reads the file and sends the statements to a database server (or, for SQLite, to a database file). It's how database structure, data and changes travel between people, servers and version control.

  • Schema scripts create tables, indexes and views for a new database.
  • Migrations are small numbered scripts that change an existing database step by step, applied in order by a tool.
  • Dumps are backups: a script that recreates a whole database, data included, written by pg_dump, mysqldump or SQLite's .dump.
  • Seed data and reports: inserts for test data, or saved queries someone runs by hand.

Three things a SQL file is not:

  • Not a database. The data lives in the database server or in a database file (.db or .sqlite for SQLite, .mdf for SQL Server). A .sql file is instructions, though a dump can contain every row as INSERT or COPY statements.
  • Not one language. The ISO standard is the common core, and every database extends it differently. A script written for MySQL often fails on PostgreSQL, and the other way round.
  • Not safe to run blindly. It can delete tables as easily as create them. Read a script, and try it on a copy, before running it against data you care about.

Anatomy

What's inside a SQL file

A SQL script is a list of statements separated by semicolons. The database runs them top to bottom, exactly as if you typed them one by one. This small script, which runs unchanged on PostgreSQL, MySQL and SQLite, uses the main kinds, part by part.

library.sql
-- library.sql: books and loans
DROP TABLE IF EXISTS loans;
DROP TABLE IF EXISTS books;

CREATE TABLE books (
    id     INTEGER      PRIMARY KEY,
    title  VARCHAR(200) NOT NULL,
    year   INTEGER      CHECK (year > 1400)
);

CREATE TABLE loans (
    book_id  INTEGER     NOT NULL REFERENCES books (id),
    borrower VARCHAR(80) NOT NULL,
    due_on   DATE        NOT NULL
);

INSERT INTO books (id, title, year) VALUES
    (1, 'Example Tales', 1998),
    (2, 'The O''Example Atlas', 2021);

BEGIN;
INSERT INTO loans VALUES (2, 'Ada Example', '2026-11-10');
COMMIT;

/* Which books are out, and until when? */
SELECT b.title, l.borrower, l.due_on
FROM books b
JOIN loans l ON l.book_id = b.id
ORDER BY l.due_on;
  1. 1-- library.sql: books and loans

    A comment

    Two hyphens start a comment that runs to the end of the line. MySQL needs a space after them. /* … */ comments can span lines.

  2. 2DROP TABLE IF EXISTS loans;

    Starting clean

    Deletes the table if it's there, so the script can run twice. loans goes first because it refers to books. On a real database this deletes data: read a script before you run it.

  3. 3CREATE TABLE books ( … );

    Data definition (DDL)

    Defines a table: its columns, their types and the rules the data must follow. CREATE, ALTER and DROP change the structure, not the data.

  4. 4PRIMARY KEY / NOT NULL / CHECK (year > 1400)

    Constraints

    Rules the database enforces on every row. An insert that breaks one fails with an error instead of storing bad data.

  5. 5REFERENCES books (id)

    A foreign key

    Every loan must point at a book that exists. SQLite only enforces this after PRAGMA foreign_keys = ON; PostgreSQL and MySQL always do.

  6. 6INSERT INTO books … VALUES …;

    Data manipulation (DML)

    Adds rows; UPDATE changes them and DELETE removes them. Several rows can go in one statement.

  7. 7'The O''Example Atlas'

    A string literal

    Text goes in single quotes, and a quote inside the text is written twice. Double quotes are for names of tables and columns in standard SQL, not for text.

  8. 8BEGIN; … COMMIT;

    A transaction

    The statements in between take effect together, at COMMIT, or not at all if you ROLLBACK.

  9. 9SELECT … FROM books b JOIN loans l …

    A query

    Reads data, here combining two tables. A script's queries print their results in the terminal or tool that runs it.

  10. 10ORDER BY l.due_on;

    The final semicolon

    Ends the last statement. Command-line clients wait for it before sending a statement to the database.

How to

How to run a .sql file

Each database has a command-line client that reads a script from a file. Open a terminal (Command Prompt or PowerShell on Windows, Terminal on macOS and Linux) and run:

Terminal
# PostgreSQL: stop at the first error; -1 runs it all in one transaction
psql -d shop -v ON_ERROR_STOP=1 -f script.sql
psql -d shop -v ON_ERROR_STOP=1 -1 -f script.sql

# MySQL or MariaDB: stops at the first error unless you add --force
mysql --default-character-set=utf8mb4 shop < script.sql

# SQLite: creates shop.db if it doesn't exist; -bail stops at the first error
sqlite3 -bail shop.db < script.sql

# SQL Server: put ":On Error exit" at the top of the script to stop at the first error
sqlcmd -S localhost -d shop -i script.sql
On an error, by defaultInside an interactive session
psql (PostgreSQL)Prints it and carries on with the next statement\i script.sql
mysql (MySQL, MariaDB)Stopssource script.sql
sqlite3 (SQLite)Prints it, carries on, and exits with an error code.read script.sql
sqlcmd (SQL Server)Prints it; :On Error exit in the script makes it stop:r script.sql
  • Graphical tools: in SSMS (SQL Server Management Studio), DBeaver, pgAdmin or MySQL Workbench, open the file and click Execute or Run. On Windows, double-clicking a .sql file usually opens it in SSMS or an editor, depending on what's installed; it doesn't run it.
  • The database must exist first, unless the script creates it. createdb shop (PostgreSQL), CREATE DATABASE shop (MySQL) or simply naming a new file (SQLite) does that.
  • The output of SELECT statements goes to the terminal. Add -o file.txt to psql or redirect with > out.txt to keep it.

Compatibility

Why a script for one database fails on another

RFC 6922, which registered application/sql, says it plainly: although a standard exists, vendor implementations vary significantly. The basics in the anatomy above work almost everywhere; these are the places where they differ:

PostgreSQLMySQLSQLiteSQL Server
Quoting names"name"Backticks around the name"name", or backticks[name] or "name"
Auto-numbered keyGENERATED ALWAYS AS IDENTITY or SERIALAUTO_INCREMENTINTEGER PRIMARY KEYIDENTITY(1,1)
Joining stringsa || bCONCAT(a, b)a || ba + b or CONCAT
First n rowsLIMIT nLIMIT nLIMIT nTOP (n) or OFFSET … FETCH
True and falsebooleanTINYINT(1), written TRUE/FALSEIntegers 1 and 0BIT
Backslash in stringsPlain characterEscape characterPlain characterPlain character
CREATE TABLE inside a transactionRolled back with the restCommits the transaction firstRolled back with the restRolled back with the rest
Client-only commands in scripts\set, \echo, \copy…DELIMITER, source.read, .mode…GO, :r, :setvar
  • Unquoted names change case. PostgreSQL folds them to lowercase, so CREATE TABLE Users makes users, and SELECT * FROM "Users" then fails. The SQL standard folds to uppercase instead. Either always quote a name or never quote it.
  • Types are looser in SQLite. It gives a DECIMAL(10,2) column numeric affinity and ignores the precision, so 19.00 comes back as 19 and a sum as 34.0.
  • Client commands aren't SQL. Lines like \set, DELIMITER // or GO are read by one particular client and never reach the server. Run the script in another tool and they're syntax errors.
sqlserver.sql
-- The same idea in Transact-SQL (SQL Server), run with sqlcmd or SSMS
CREATE TABLE dbo.books (
    id    INT IDENTITY(1,1) PRIMARY KEY,
    title NVARCHAR(200) NOT NULL
);
GO

BEGIN TRANSACTION;
INSERT INTO dbo.books (title) VALUES (N'Example Tales');
COMMIT TRANSACTION;
GO

SELECT TOP (5) id, title FROM dbo.books ORDER BY id;
GO

Backups and changes

Dump files vs migration files

DumpMigration
Made bypg_dump, mysqldump, sqlite3 db .dumpA person, often with a framework's help
ContainsThe whole database: structure and every rowOne change: add a column, create an index, fix some data
Typical nameshop-2026-10-27.sqlV3__add_phone_column.sql, 20261027_add_phone.up.sql
AppliedOnce, into an empty databaseIn order, each one once, by a tool that remembers which have run
Portable between databasesNo: full of the source database's dialectUsually written for one database
  • Restore a PostgreSQL dump into a new, empty database with psql -X -d newdb -f dump.sql. A plain-text dump loads its data with COPY … FROM stdin blocks, which only psql understands. Dumps in pg_dump's custom format (-Fc) aren't SQL at all and need pg_restore.
  • Restore a MySQL dump with mysql newdb < dump.sql. A dump made with --databases or --all-databases contains its own CREATE DATABASE and USE statements.
  • Recent pg_dump versions start the file with a \restrict line and a random key, and end it with \unrestrict. In between, psql refuses all other backslash commands, a fix for CVE-2025-8714, in which a malicious superuser of the source server could plant commands in a dump to run on the computer restoring it.

Doing it safely

Transactions in scripts: all or nothing

When a script fails halfway, the statements before the error have already run. Without a transaction, you're left with half a change: a table created but not filled, money taken from one account but not added to the other.

  • Wrap related changes in BEGIN; … COMMIT; (START TRANSACTION in MySQL, BEGIN TRANSACTION in SQL Server).
  • In psql, combine --single-transaction with ON_ERROR_STOP. psql then sends BEGIN first and COMMIT at the end, or ROLLBACK if anything fails. PostgreSQL's documentation suggests both options for restoring dumps.
  • In MySQL, DDL ends the transaction. CREATE TABLE, ALTER TABLE and DROP TABLE commit whatever was pending before they run, and can't be rolled back. sample-mysql.sql below shows a row surviving a ROLLBACK for this reason.
  • Make scripts safe to re-run with IF EXISTS and IF NOT EXISTS, so running one twice doesn't fail or duplicate data.

Characters

Encoding: why names turn into é in the database

A SQL file doesn't say which encoding it's in, and RFC 6922 warns against guessing. The client reads the bytes in its own client encoding and the server converts them to the database's encoding. If the client guesses wrong, the database stores the wrong characters, and the damage is permanent until someone fixes the data.

  • Save scripts as UTF-8. In our tests, psql 16, the MySQL 8.0 client and sqlite3 3.45 all accepted a UTF-8 byte order mark and CRLF line endings, but older tools may not.
  • MySQL: use utf8mb4. MySQL's older utf8 (now called utf8mb3) stores at most 3 bytes per character, so it can't hold emoji. The MySQL manual recommends utf8mb4 for everything new.
  • MySQL: name the client character set. The mysql client picks its character set from the system locale. On a server with no UTF-8 locale, that can be latin1, and UTF-8 text gets stored double-encoded. Run mysql --default-character-set=utf8mb4 or start the script with SET NAMES utf8mb4;.
  • PostgreSQL: the client encoding depends on how psql is started and on the PGCLIENTENCODING variable. SET client_encoding = 'UTF8'; at the top of a script removes the doubt, and pg_dump writes that line for you.

Troubleshooting

Errors people hit when running SQL files

ErrorUsual causeFix
PostgreSQL: syntax error at or near "AUTO_INCREMENT"A MySQL script run on PostgreSQL (or any script in the wrong dialect)Convert the dialect-specific parts, or run it on the database it was written for
MySQL: ERROR 1064 You have an error in your SQL syntaxA typo, a reserved word used as a name, or another dialect's syntaxCheck the statement at the line number shown; quote names with backticks
relation "Users" does not existPostgreSQL folded an unquoted Users to users, or the table is in another schema or databaseUse the same quoting everywhere; check you're connected to the right database
ERROR 1046 (3D000): No database selectedmysql < script.sql without a database name, and no USE in the scriptmysql shop < script.sql, or add USE shop; at the top
Illegal mix of collationsMySQL comparing two strings stored with different collations, for example a column and a procedure parameterUse one character set and collation for the whole database, or COLLATE in the comparison
Incorrect string value: '\xF0\x9F\x91\x8B' for columnEmoji or other 4-byte characters going into a MySQL utf8mb3 columnConvert the table to utf8mb4
duplicate key value violates unique constraintThe script ran twice, or into a database that already had the dataRestore into an empty database; use IF NOT EXISTS or upserts for re-runnable scripts
A dump restore that stops halfwayAn error early on (a missing role, an existing table), with later statements depending on itRestore into an empty database with ON_ERROR_STOP and fix the first error, not the last

Security

Opening, editing and security: SQL injection and dumps

Any text editor opens a .sql file. VS Code, JetBrains DataGrip and DBeaver add syntax highlighting and can run the statements against a connection; formatters such as pg_format and sqlfluff tidy and check them. Opening the file runs nothing.

  • Running a script is running code. It can drop tables, change permissions or, in some databases, read server files. Run scripts from others as a database user with only the rights the script needs, and against a copy first.
  • Dumps contain everything. Customer names, email addresses, password hashes and anything else in the database ends up in the file in readable text. Treat a dump like the database itself: encrypt it, limit who has it, and delete old ones. Under the GDPR, personal data in a backup is still personal data.
  • Dumps can carry client commands. psql backslash commands such as \!, which runs a shell command, are why recent pg_dump versions add \restrict. Only restore dumps from sources you trust.

SQL injection is the best-known database attack, and it happens in application code, not in .sql files. It occurs when a program builds a query by pasting user input into SQL text: if the input contains a quote, the rest of it is read as SQL, and the attacker can change what the query does, for example to return every row instead of one. The fix, as the OWASP cheat sheet sets out, is parameterised queries (prepared statements): the query is sent with placeholders, and the values travel separately, so they are never read as SQL. Escaping input by hand is unreliable, and least-privilege database accounts limit the damage if something slips through.

Free downloads

Sample SQL files to download

Free sample SQL files for testing database clients, migration tools, syntax highlighters, upload filters and size limits. All data is fictional. We ran each one on PostgreSQL 16, MySQL 8.0 and SQLite 3.45 (the dialect-specific ones on their own database) and parsed them with sqlglot and pglast.

sample-schema.sql · 4.8 KBDownloadOpen
Loading…

What's inside sample-schema.sql

The file is commented: open it in a text editor and each numbered comment marks one of these parts. It runs unchanged on PostgreSQL, MySQL and SQLite, so it's a good first test of any SQL tool.

  1. Comments 1 and 2: comments and a clean start

    Both comment styles, then DROP VIEW IF EXISTS and DROP TABLE IF EXISTS in dependency order, so the script can run again.

  2. Comments 3 to 6: tables

    Four tables with primary keys, UNIQUE, NOT NULL, DEFAULT and CHECK constraints, exact DECIMAL money columns, foreign keys and an index.

  3. Comment 7: data

    Multi-row INSERT statements with fictional customers, products and orders. A name with an apostrophe shows quote doubling; dates are written YYYY-MM-DD.

  4. Comment 8: a transaction

    Two UPDATE statements between BEGIN and COMMIT, after all the DDL, so MySQL's implicit commits don't interfere.

  5. Comment 9: a view

    order_totals joins three tables and sums each order; later queries select from it like a table.

  6. Comments 10 to 12: queries

    Results you can check: orders 101, 102 and 103 total 34.00, 19.00 and 40.00; Ada Example spent 74.00 in total; a LEFT JOIN with COUNT and LIMIT.

All sample SQL files

  • Portable schema, data and queries

    sample-schema.sql · 4.8 KB (4,932 bytes)

    A small shop database that runs unchanged on PostgreSQL, MySQL and SQLite: tables with constraints and foreign keys, an index, inserts, a transaction, a view and three queries with known results, with numbered comments.

    • A first test of any SQL client, tool or highlighter
    • Teaching DDL, DML, transactions and joins
  • PostgreSQL script with psql commands

    sample-postgresql.sql · 3.0 KB (3,056 bytes)

    \set ON_ERROR_STOP, an enum type, an identity column, TIMESTAMPTZ, JSONB queries, a PL/pgSQL function in dollar quotes, ON CONFLICT upserts, RETURNING, and a CREATE TABLE rolled back inside a transaction.

    • Testing PostgreSQL-specific syntax in tools and highlighters
    • Showing what psql-only lines look like
  • MySQL script with DELIMITER and a procedure

    sample-mysql.sql · 2.7 KB (2,803 bytes)

    SET NAMES utf8mb4, backtick quoting, AUTO_INCREMENT, a JSON column, backslash escapes, ON DUPLICATE KEY UPDATE, a stored procedure defined with DELIMITER, and a row that survives ROLLBACK because CREATE TABLE committed it.

    • Testing MySQL-specific syntax and the DELIMITER command
    • Demonstrating implicit commits
  • Real pg_dump output

    sample-pg-dump.sql · 5.5 KB (5,648 bytes)

    The database from sample-schema.sql, dumped by pg_dump 16 in plain format with --no-owner --no-privileges, unedited apart from a comment block at the top: SET lines, \restrict, CREATE TABLE, COPY … FROM stdin data blocks and constraints added after the data.

    • Testing restore pipelines and dump parsers
    • Seeing what a real dump file looks like
  • UTF-8 with BOM and CRLF, many scripts

    sample-utf8-bom-crlf.sql · 1.9 KB (1,923 bytes)

    Starts with the UTF-8 byte order mark and uses Windows line endings. Inserts greetings in 15 languages and scripts, including Arabic, Hindi, Chinese, emoji and curly quotes, then selects them back.

    • Spotting encoding problems in clients, imports and pipelines
    • Testing BOM and CRLF handling
  • 100 KB SQL file

    sample-100kb.sql · 100 KB (102,400 bytes)

    A portable script that creates one table and inserts 2,200 fictional sensor readings in batches of 100 rows, padded with comment lines to exactly 102,400 bytes.

    • Upload and size-limit tests
    • Import speed and batch-size tests

Ways to test with them

  • Clients and CI: run sample-schema.sql with your client and compare the results: order totals 34.00, 19.00 and 40.00, then Ada Example with 2 orders and 74.00.
  • Error handling: add a typo to a copy of sample-schema.sql and run it with and without ON_ERROR_STOP (psql), --force (mysql) or -bail (sqlite3), to see whether your pipeline stops where you expect.
  • Encoding: load sample-utf8-bom-crlf.sql and select the rows back. Any Ã, †or ? means a step didn't treat the file as UTF-8; in MySQL, also check the column is utf8mb4.
  • Restores: create an empty PostgreSQL database and restore sample-pg-dump.sql with psql -X -v ON_ERROR_STOP=1; SELECT * FROM order_totals should match the schema sample.
  • Upload limits: sample-100kb.sql is exactly 102,400 bytes and inserts exactly 2,200 rows.

Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.

Put it online

Have a SQL file? Give it a link.

Drop a .sql file on 99helpers and it gets its own web address. Anyone who opens the link reads the script as plain text in their browser: it is never executed against any database, which makes it a simple way to share a schema, a migration or a query for review.

Questions

SQL files, frequently asked

What is a .sql file?

A plain-text script of SQL statements: commands that create tables, add or change data and run queries. A database client reads it and sends the statements to a database.

How do I open a .sql file?

Any text editor shows it, from Notepad to VS Code. To run it, open it in a database tool such as SSMS, DBeaver, pgAdmin or MySQL Workbench, or use a command-line client.

How do I run a .sql file?

With the client for your database: psql -d mydb -f file.sql for PostgreSQL, mysql mydb < file.sql for MySQL, sqlite3 my.db < file.sql for SQLite, or sqlcmd -i file.sql for SQL Server.

How do I import a .sql file into MySQL?

Create the database, then run mysql -u user -p mydb < file.sql in a terminal, or source file.sql at the mysql> prompt. In MySQL Workbench, use Server, Data Import, or open the file and execute it.

Why does my SQL file work in MySQL but not in PostgreSQL?

Each database speaks its own dialect. Backtick quoting, AUTO_INCREMENT, backslash escapes and DELIMITER are MySQL-only; PostgreSQL uses double quotes, identity columns and dollar quoting. Scripts have to be converted, by hand or with a tool.

Is a .sql file a database?

No. It's a text file of instructions. The data lives in the database server, or in a .db or .sqlite file for SQLite. A dump file can recreate a database, including all its data.

Is it safe to open a .sql file?

Opening it in an editor is safe; it's text. Running it is different: a script can delete or change data. Read it first and try it on a copy. Dumps may also contain personal data and should be kept private.

What is the MIME type of a .sql file?

application/sql, registered in RFC 6922 in 2013. Some systems send text/x-sql or text/plain instead.

Related formats

Other file types explained

Keep going

Related

Sources

Last reviewed 27 October 2026.