JSONToonPro
JSON converter tool

JSON to SQL Converter Online

Convert JSON arrays, objects, and API responses into SQL CREATE TABLE schemas and INSERT statements in one click. Choose PostgreSQL, MySQL, or SQLite, flatten nested JSON, infer column types, and download a ready to use SQL file. Everything runs locally in your browser.

100% client sidePostgreSQL, MySQL, SQLiteCopy and download
3 x 9
Input/ JSON
749 chars41 lines
Output/ PostgreSQL SQL
704 chars18 lines

From an Array to a Table

Generating SQL from JSON is really two jobs. The first is inferring a schema: scanning every record to work out which columns exist and what type each one should be. The second is serialising the values into INSERT statements with correct quoting and escaping.

The schema is inferred from the union of keys across all records, not just the first one, because JSON arrays are frequently ragged. A key that appears in only some records still needs a column, and the records that lack it get NULL. If a key holds a number in one record and a string in another, the widening rule applies and the column becomes text, since text can hold anything.

Side by Side Example

An orders array and the DDL plus DML it generates.

JSON input

[
{ "order_id": 1001,
"customer": "Nadia O'Brien",
"total": 249.99,
"paid": true,
"shipped_at": null },
{ "order_id": 1002,
"customer": "Ravi Patel",
"total": 18.00,
"paid": false,
"shipped_at": "2025-02-14" }
]

SQL output

CREATE TABLE orders (
order_id INTEGER,
customer VARCHAR(255),
total DECIMAL(12,2),
paid BOOLEAN,
shipped_at VARCHAR(255)
);
 
INSERT INTO orders
(order_id, customer, total, paid, shipped_at)
VALUES
(1001, 'Nadia O''Brien', 249.99, TRUE, NULL),
(1002, 'Ravi Patel', 18.00, FALSE, '2025-02-14');

The apostrophe in the customer name is escaped by doubling it, which is the SQL standard mechanism. The null stays a real NULL rather than the four character string.

Type Inference Mapping

JSON typeTypical SQL typeNotes
String, shortVARCHAR(255)Length chosen from the longest observed value, rounded up
String, long or unboundedTEXTAnything over a few hundred characters
Integer within 32 bitsINTEGERSafe for ids and counts
Integer beyond 32 bitsBIGINTTimestamps in milliseconds land here
Float, money-likeDECIMAL(12,2)Never use a binary float for currency
Float, scientificDOUBLE PRECISIONMeasurements and ratios
BooleanBOOLEAN or TINYINT(1)MySQL has no true boolean type
Null only, no other valuesTEXT NULLNothing to infer from, widen to text
ISO date stringDATE or TIMESTAMPOnly if you opt into date detection
ObjectJSON, JSONB, or a child tableDepends on how you will query it
ArrayJSON, JSONB, or a join tableSame decision, see normalisation below

Inferred lengths are a starting point, not a contract. If your sample happens to contain no name longer than forty characters, a VARCHAR sized to that sample will reject real data later. Widen anything that a user can type into.

Dialect Differences

FeatureMySQLPostgreSQLSQLite
Identifier quotingBackticksDouble quotesEither
Auto increment keyAUTO_INCREMENTSERIAL or IDENTITYINTEGER PRIMARY KEY
BooleanTINYINT(1), 0 and 1Native BOOLEAN, TRUE and FALSEStored as 0 and 1
JSON columnJSONJSON and JSONB, JSONB preferredTEXT with JSON functions
Text typeVARCHAR or TEXTTEXT, no length penaltyTEXT, types are advisory
Multi-row insertSupportedSupportedSupported since 3.7.11
UpsertON DUPLICATE KEY UPDATEON CONFLICT DO UPDATEON CONFLICT DO UPDATE

PostgreSQL folds unquoted identifiers to lower case while MySQL on Linux is case sensitive for table names but not column names. The simplest way to avoid ever thinking about this is to generate snake_case identifiers and never quote them.

Handling Nested Objects and Arrays

Relational tables are flat, so nested JSON forces a modelling decision. There are three options and the right one depends entirely on how you intend to query the data.

StrategyResultGood whenCost
Flatten with dot or underscore pathsaddress_city, address_postcode columnsNesting is shallow and fixedColumn explosion if the shape varies
Store as a JSON columnOne address column holding the objectShape varies or you rarely filter on itIndexing and joining are awkward
Normalise into a child tableAn addresses table with a foreign keyYou query, join, or aggregate on itMore work up front, more joins later

Arrays of scalars can live in a JSON column comfortably. Arrays of objects almost always want their own table, because a line items array inside an orders row is a one to many relationship pretending not to be one. Generated SQL will usually take the JSON column route since it is the only option that never loses data, and promoting it to a proper child table is a deliberate follow up step.

A Warning About Generated SQL

Generated statements are for schema bootstrapping and seeding: creating a table from a sample payload, loading fixtures into a development database, or getting a prototype moving. That is a safe use because you control the input and you can read the output before running it.

String concatenation is never acceptable in application code. Building a query by interpolating values into a string is the definition of a SQL injection vulnerability, and escaping by hand does not save you: encodings, multi-byte characters, and dialect specific escape modes all provide ways around a naive escaper.

Never versus always

// Never, in any language, for any reason
db.query("SELECT * FROM users WHERE email = '" + input + "'");
 
// Always, parameters sent separately from the statement
db.query("SELECT * FROM users WHERE email = $1", [input]);

Two more habits worth keeping. Review generated DDL before you run it, since inferred types and lengths reflect one sample rather than your real domain. And add the things inference cannot see: primary keys, foreign keys, unique constraints, NOT NULL, and the indexes your queries will actually need.

Getting data into a database is one step in a longer pipeline. See the full converter collection for JSON to CSV when your loader prefers a bulk import file, JSON Schema to validate payloads before they ever reach the database, and JSON to TypeScript to type the rows in your application layer.

How to convert JSON to SQL

Three steps, zero setup
01

Paste JSON data

Add a JSON array, object, API response, or seed data export. Use the sample button to test nested fields and arrays.

02

Pick SQL options

Set table name, choose PostgreSQL, MySQL, or SQLite, then toggle schema generation, nested flattening, and identifier quoting.

03

Copy or download SQL

Generate SQL live as you type. Copy it into your SQL client or download a .sql file for imports, seeds, and migration drafts.

Built for seed data and imports

Turn JSON exports into practical SQL for local databases, demos, test fixtures, admin imports, and migration drafts without sending sample records anywhere.

100% client side

Data stays in your browser. No uploads, server logs, or database payload storage.

Instant SQL output

Generate CREATE TABLE and INSERT statements immediately from JSON input.

Dialect aware

PostgreSQL, MySQL, and SQLite options tune booleans, JSON types, and identifiers.

Nested JSON ready

Flatten nested keys into columns or preserve objects and arrays as JSON values.

SQL to JSON

Parse common INSERT statements back into clean JSON for inspection or reuse.

SQL workflow

Copy SQL or download a ready to use file for imports, seeds, and drafts.

Frequently asked questions

8 answers
Paste a JSON object or JSON array into the input panel. Choose a table name and database dialect, then the converter generates CREATE TABLE and INSERT statements instantly. Copy the SQL or download it as a .sql file.

SQL INSERT to JSON Converter

Need to go the other direction? The SQL to JSON tab converts common INSERT INTO statements back to structured JSON arrays. Paste your SQL INSERT statements and get clean JSON output for re-importing, testing, or working with your data in JavaScript, Python, or any other language.

More JSON Tools