Format a Batch SQL INSERT
Batch INSERT statements are one of the most practical SQL patterns for developers: they populate seed data for development environments, create test fixtures for automated tests, migrate data between table schemas, and seed production databases with initial reference data like product categories or country codes. When stored in migration files and committed to version control, they become part of the project's data history. The key performance advantage of batch INSERT over individual INSERT statements is dramatic: a single INSERT with 1000 value rows can be 10–100 times faster than 1000 individual INSERT statements. Each INSERT statement requires a round-trip to the database server, transaction overhead, and parsing. Batching eliminates most of this overhead. Database documentation typically recommends batches of 500–1000 rows before the packet size limit becomes a concern. This example inserts five products into a products table with id, name, price, category_id, and in_stock columns. Without formatting, this could be a single line spanning hundreds of characters. The formatter places each value row on its own line, making it trivial to review changes in a pull request: if a price is wrong, the diff shows exactly which row changed rather than requiring a careful character-by-character comparison of a single long line. Key parts explained: the VALUES keyword introduces the list of row tuples, each enclosed in parentheses and separated by commas. String values use single quotes. Boolean values use true/false (PostgreSQL, MySQL 5.7+) or 1/0 (older MySQL). The trailing semicolon terminates the statement — important in migration scripts where multiple statements run in sequence. Real-world scenarios: populating a fresh development database after checking out a new project; creating a repeatable set of test fixtures for integration tests; migrating a lookup table from one system to another; bulk-loading reference data from a CSV export using the CSV-to-SQL converter to generate the INSERT statement. Tips: for very large data sets, use database-native bulk loading commands (PostgreSQL's COPY, MySQL's LOAD DATA INFILE) which are significantly faster than INSERT for millions of rows. For batch INSERTs that may conflict with existing rows, use INSERT ... ON CONFLICT DO UPDATE (PostgreSQL) or INSERT ... ON DUPLICATE KEY UPDATE (MySQL) to create an upsert.
INSERT INTO products (id, name, price, category_id, in_stock) VALUES (1, 'Wireless Keyboard', 79.99, 3, true), (2, 'USB-C Hub', 49.99, 3, true), (3, 'Monitor Stand', 34.99, 4, false), (4, 'Desk Lamp', 28.99, 4, true), (5, 'Webcam 1080p', 89.99, 3, true);
FAQ
- Is a batch INSERT faster than individual INSERTs?
- Yes. A single INSERT with multiple value rows is significantly faster than separate INSERT statements because it reduces network round-trips and transaction overhead.
- How many rows can I insert in one statement?
- Most databases support thousands of rows per batch INSERT, but very large batches may hit packet size limits. Split into batches of 500–1000 rows for safety.
- What is the difference between INSERT and UPSERT?
- INSERT adds new rows and fails if a key already exists. UPSERT (INSERT ... ON CONFLICT or REPLACE INTO) inserts new rows or updates existing rows when a constraint is violated.
Related Examples
CREATE TABLE statements are the foundation of relational database design, and th...
Format a SQL UPDATE with WHEREUPDATE statements are among the most dangerous SQL commands to write incorrectly...
Format a SQL SELECT with JOINMulti-table JOIN queries are the workhorse of relational database development, b...