JSON to SQL Converter

Paste a JSON array of objects and get SQL you can run: a CREATE TABLE with inferred column types followed by INSERT statements. Everything is generated locally; no data is uploaded.

JSON → SQL

Input

Settings

History

Load from URL

From API data to database rows

Loading JSON into a relational database usually means writing a throwaway script. This page replaces the script for the common cases: seeding a development database from an API response, turning a fixture file into SQL for a migration, or moving a few hundred records between systems by hand.

Each object in the array becomes one row and each key a column. A single object is treated as a one-row table, and an array of plain values becomes a single column called value. Columns are the union of keys across all objects, so a key missing from one row simply yields NULL there.

Options

  • Table name (default records) is the target table. A schema-qualified name such as sales.orders is quoted part by part.
  • Dialect chooses PostgreSQL (default), MySQL, SQLite, T-SQL (SQL Server) or Standard SQL. It controls identifier quoting, literal escaping and column types.
  • Include CREATE TABLE (on by default) prefixes the inserts with a table definition. Turn it off when the table already exists.
  • One multi-row INSERT (off by default) writes INSERT … VALUES (…), (…); instead of one statement per row. Batches hold at most 1,000 rows, the limit SQL Server places on a VALUES list.

How column types are inferred

Every value in a column is inspected, so the type fits all rows, not just the first:

  • Whole numbers become INTEGER/INT, widening to BIGINT past 32 bits and to an exact decimal past 64 bits.
  • Decimals become NUMERIC in PostgreSQL and DECIMAL(p,s) sized from the data elsewhere, so 19.99 is never stored as a float. Numbers in exponent notation use the dialect’s double type.
  • true/false become BOOLEAN, TINYINT(1) in MySQL or BIT (written 1/0) in SQL Server.
  • Strings shaped like 2024-03-11 become DATE; ISO timestamps become TIMESTAMP, TIMESTAMPTZ, DATETIME or DATETIME2/DATETIMEOFFSET depending on the dialect and on whether they carry an offset.
  • Nested objects and arrays are stored as JSON text, typed JSONB in PostgreSQL and JSON in MySQL, and as plain text elsewhere.
  • A column mixing kinds (numbers and words, say) falls back to text, and a column that is always null is TEXT.

SQLite has no exact decimal or date types, so its output uses REAL only when doubles hold the values exactly and TEXT otherwise. The Info panel lists the chosen type for every column.

Quoting and escaping per dialect

Identifiers are always quoted, so keys like order, select or first name work: "order" for PostgreSQL, SQLite and standard SQL, backticks for MySQL, [order] for SQL Server. Quote characters inside names are doubled.

String literals use single quotes with ' doubled ('O''Brien'). MySQL additionally doubles backslashes, because it treats them as escapes by default. SQL Server literals containing non-ASCII text get the N'…' prefix so Unicode survives. Numbers keep their exact JSON digits.

Check the result with the SQL formatter before running it. Generating the SQL happens in your browser, which keeps production records off third-party servers.

Examples

Customers for PostgreSQL

joined becomes DATE, balance mixes integers and decimals so it becomes NUMERIC, and the apostrophe in O’Brien is doubled.

Input
[
  { "id": 1, "name": "Aisha Tan", "city": "Singapore", "joined": "2024-03-11", "balance": 1520.5 },
  { "id": 2, "name": "Ben O'Brien", "city": "Lagos", "joined": "2023-11-02", "balance": 88 },
  { "id": 3, "name": "Chloé Martin", "city": "Paris", "joined": "2025-01-20", "balance": -12.75 }
]
Output
CREATE TABLE "customers" (
  "id" INTEGER,
  "name" TEXT,
  "city" TEXT,
  "joined" DATE,
  "balance" NUMERIC
);

INSERT INTO "customers" ("id", "name", "city", "joined", "balance") VALUES (1, 'Aisha Tan', 'Singapore', '2024-03-11', 1520.5);
INSERT INTO "customers" ("id", "name", "city", "joined", "balance") VALUES (2, 'Ben O''Brien', 'Lagos', '2023-11-02', 88);
INSERT INTO "customers" ("id", "name", "city", "joined", "balance") VALUES (3, 'Chloé Martin', 'Paris', '2025-01-20', -12.75);
Open this example in the tool

Nested JSON into MySQL

items is stored in a JSON column, placed_at becomes DATETIME, total becomes DECIMAL(5,2) and both rows share one INSERT.

Input
[
  { "id": "ord_1", "placed_at": "2026-09-14 08:21:05", "total": 129.90, "items": [{ "sku": "KB-104", "qty": 1 }], "paid": true },
  { "id": "ord_2", "placed_at": "2026-09-14 09:02:44", "total": 79.00, "items": [{ "sku": "MS-220", "qty": 2 }], "paid": false }
]
Output
CREATE TABLE `shop`.`orders` (
  `id` VARCHAR(5),
  `placed_at` DATETIME,
  `total` DECIMAL(5,2),
  `items` JSON,
  `paid` TINYINT(1)
);

INSERT INTO `shop`.`orders` (`id`, `placed_at`, `total`, `items`, `paid`) VALUES
  ('ord_1', '2026-09-14 08:21:05', 129.90, '[{"sku":"KB-104","qty":1}]', TRUE),
  ('ord_2', '2026-09-14 09:02:44', 79.00, '[{"sku":"MS-220","qty":2}]', FALSE);
Open this example in the tool

Inserts only, for SQL Server

No CREATE TABLE is written, booleans become 1 and 0, and the name with ë gets an N prefix.

Input
[
  { "Id": 1, "Name": "Zoë", "Active": true },
  { "Id": 2, "Name": "Ben", "Active": false }
]
Output
INSERT INTO [dbo].[Users] ([Id], [Name], [Active]) VALUES (1, N'Zoë', 1);
INSERT INTO [dbo].[Users] ([Id], [Name], [Active]) VALUES (2, 'Ben', 0);
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
Expected every row to be an object, but found a stringThe array mixes objects with other values, so columns cannot be derived.Keep only objects in the array, or convert the other values separately.
There are no data rows, so no INSERT statements were writtenA warning: the JSON array is empty.Paste an array that contains at least one object.
Column "id" appears twice (names are case-insensitive in SQL); renamed to "id_2"Two keys differ only in letter case, such as Id and id, which most databases treat as the same column.Rename one of the keys in the JSON, or keep the generated id_2 column.
Unexpected end of input
Explained
The pasted JSON is incomplete.Copy the whole array, including the final ].

Frequently asked questions

Which databases are supported?

PostgreSQL, MySQL, SQLite, SQL Server (T-SQL) and a standard SQL flavour. MariaDB users can pick MySQL.

How are nested objects stored?

As JSON text in one column, typed JSONB in PostgreSQL and JSON in MySQL. Other dialects get a text column.

Why are all column names quoted?

Quoting makes reserved words, spaces and mixed case safe in every dialect. Remove the quotes only if you are sure the names are plain identifiers.

Can I generate one INSERT for many rows?

Yes, enable One multi-row INSERT. Rows are grouped into statements of up to 1,000 rows each.

Is decimal precision preserved?

Yes. Decimals are typed NUMERIC or DECIMAL(p,s) and inserted with their exact JSON digits, never through a floating-point type unless the input uses exponent notation.

Related tools