---
url: https://findutils.com/guides/sql-to-json
title: "Convert SQL INSERT Statements to JSON With the Right Types"
description: "Turn a mysqldump, SQLite dump or INSERT statements into JSON: NULL to null, numbers and booleans typed, zip codes kept as text. Runs in your browser."
category: converters
content_type: guide
guide_type: subtopic
cluster: data-conversion
locale: en
read_time: 8
status: published
author: "olgunozoktas"
published_at: 2026-09-26T12:00:00Z
excerpt: "A seed file, a test fixture or a mock API needs the rows that sit in a SQL dump, as JSON. Converting the INSERT statements as text, without restoring a database, gets them out; the useful part is getting the types right, so 42 is a number, NULL is null and 007 stays 007."
tag_ids: ["sql", "json", "data-conversion", "database"]
tags: ["SQL", "JSON", "Data Conversion", "Database"]
primary_keyword: "sql to json"
secondary_keywords: ["convert sql insert to json", "mysqldump to json", "sql dump to json", "insert statements to json array", "sqlite dump to json"]
tool_tag: "sql-to-json"
related_tool: "sql-to-json"
related_tools: ["sql-to-json", "sql-to-csv", "json-to-sql", "csv-to-sql", "json-formatter"]
og_image: "/images/content/guides/sql-to-json-cover-20260926.webp"
image_alt: "Stacked metal database cylinders sending a stream of small amber and cream blocks into nested glass curly-bracket frames."
updated_at: "2026-09-26T12:00:00Z"
---

To convert SQL to JSON without restoring a database, read the rows out of the dump's `INSERT ... VALUES` statements and write each row as a JSON object keyed by column name. FindUtils [SQL to JSON](/convert/sql-to-json/) does this in your browser: it parses the SQL as text and executes nothing, turns `NULL` into `null`, `TRUE` into `true` and safe numbers into JSON numbers, and returns an array of objects, or one array per table when the dump holds several. The dump is not uploaded.

This guide covers where column names come from, the exact typing rules, which dumps work, and what is kept as text instead of being guessed.

## Why Convert a Dump to JSON?

A SQL dump is the most common way data leaves a database, and JSON is what most code wants to read:

- **Test fixtures and seed files** for a JavaScript, Python or Go project.
- **Mock API responses** built from real rows.
- **Loading a few tables into a tool** that takes JSON, not SQL.
- **Reading an old backup** when the database server that made it is gone.

For a spreadsheet instead of code, [SQL to CSV](/convert/sql-to-csv/) reads the same dumps into CSV. JSON keeps what CSV cannot: the difference between `null`, the number `42` and the string `"42"`.

## How to Convert a Dump

### Step 1: Paste or open the dump

Open [SQL to JSON](/convert/sql-to-json/) and paste the SQL, or open a `.sql` file. The preview lists every table that has rows, with its row count.

### Step 2: Choose the shape

With grouping on, a dump with rows for more than one table becomes an object keyed by table name; a single table is always a plain array. With grouping off, every row goes into one flat array, and you can add a `__table` field to each row so the rows still say where they came from.

### Step 3: Choose the typing and the format

Leave number conversion on to turn quoted values such as `'42'` into numbers when that is safe, or turn it off to keep every quoted value a string. Choose 2 or 4 spaces of indentation, or minified output.

### Step 4: Pick a table and copy

Select one table to export only that table, then copy or download the JSON.

## A Worked Example

Input:

```sql
INSERT INTO users (id, name, active, score, note)
VALUES (1, 'Ada', TRUE, 9.5, NULL), (2, 'Bob', false, -3, 'x');
```

Output with 2-space indentation:

```json
[
  {
    "id": 1,
    "name": "Ada",
    "active": true,
    "score": 9.5,
    "note": null
  },
  {
    "id": 2,
    "name": "Bob",
    "active": false,
    "score": -3,
    "note": "x"
  }
]
```

Add a second statement, `INSERT INTO orders (id, user_id) VALUES (10, 1), (11, 1);`, and the result becomes an object with a `users` array and an `orders` array.

## Where Do Column Names Come From?

SQL to JSON takes the names from the first source that has them:

1. **The INSERT's own column list**, as in `INSERT INTO users (id, name) VALUES ...`. mysqldump writes these with `--complete-insert`.
2. **A `CREATE TABLE` in the same input.** `INSERT INTO t VALUES (1, 'Ada')` after `CREATE TABLE t (id INTEGER, name TEXT)` gives `{"id": 1, "name": "Ada"}`. Table constraints such as `PRIMARY KEY (id)` are skipped.
3. **Positions**, when neither exists: `column_1`, `column_2` and so on.

Schema-qualified names keep only the last part, so `` `shop`.`users` `` and `public.users` both become the table `users`. If a later INSERT for the same table names more columns, rows with fewer values get `null` for the missing ones, and a note says so.

## How Are Values Typed?

| SQL value | JSON value | Rule |
|---|---|---|
| `NULL` | `null` | |
| `TRUE`, `false` | `true`, `false` | Unquoted, any letter case |
| `42`, `-3`, `9.5` | `42`, `-3`, `9.5` | Unquoted numbers become numbers |
| `9007199254740993` | `"9007199254740993"` | Beyond ±9007199254740991, a JSON number would change the value |
| `0.12345678901234567` | `"0.12345678901234567"` | More than 15 significant digits |
| `'42'`, `'-3.5'` | `42`, `-3.5` | Quoted, with number conversion on, when every quoted value in that column is a clean number |
| `'007'`, `'1.50'`, `'+3'`, `'1e5'`, `'-0'` | kept as strings | Converting would change the text |

Number conversion is decided per column, so one column never mixes types. A `code` column holding `'007'` and `'120'` stays all strings, because `'007'` would change; a `qty` column holding `'5'` and `'12'` becomes `5` and `12`.
| `NOW()`, `DEFAULT`, `CURRENT_TIMESTAMP` | `"NOW()"` and so on | Not evaluated; the SQL text is kept |
| `0xFF`, `b'101'` | `"0xFF"`, `"b'101'"` | Hex and bit literals are not decoded |

The rule for quoted values is strict on purpose: a quoted value becomes a number only when the number writes back as exactly the same text. That keeps zip codes, phone numbers, account numbers and prices such as `1.50` intact. Every kind of value kept as text is named once in the notes, with the first example found.

## Which Dumps Work?

| Source | Works? | Notes |
|---|---|---|
| mysqldump / MariaDB dump | Yes | Comments, `LOCK TABLES` and `/*!...*/` hints are skipped; backticks are understood |
| SQLite `.dump` | Yes | |
| `pg_dump` with `--inserts` or `--column-inserts` | Yes | |
| `pg_dump` default plain format | No | Its rows are in `COPY ... FROM stdin` blocks, which this tool does not read |
| `INSERT ... SELECT` | Skipped | It has no literal rows; the statement is listed by line |
| Custom-format `pg_dump` (`-Fc`) | No | It is a binary archive, not SQL text |

The [PostgreSQL documentation](https://www.postgresql.org/docs/current/app-pgdump.html) describes `--inserts` as dumping data "as INSERT commands (rather than COPY)", and `--column-inserts` as adding explicit column names. Re-export with `--column-inserts` to get a dump this tool can read, with names included.

## Limits and Honest Caveats

- **Nothing is executed.** The SQL is read as text, so no function runs and no default is filled in.
- **Backslash escapes are read the MySQL way.** Inside a quoted string, `\n` becomes a line break and `\'` a quote. A PostgreSQL standard string that holds a literal backslash, such as a Windows path, is changed by this.
- **Type casts after a string are dropped.** `'5'::integer` keeps the string `'5'` (converted to `5` by number conversion), and a note says the cast was dropped.
- **Large inputs are capped.** The tool reads up to about 10 MB of SQL and stops a table at 50,000 rows by default (200,000 at most through the API), saying so when it does.
- **An unclosed quote stops the conversion** and names the line where the statement starts.

## Common Mistakes

**Converting a default pg_dump.** Its rows are in COPY blocks, so you get no rows, or an error when the COPY data contains a stray quote. Re-export with `--column-inserts`.

**Expecting IDs to be numbers when the dump quotes them.** Quoted `'42'` becomes `42` only with number conversion on. Quoted `'007'` never does, by design.

**Losing track of tables in a flat array.** Turn grouping off only when you add the `__table` field, or when the dump has one table.

## Use It From Code

The same parser is the `sql_to_json` tool on the FindUtils REST API and MCP server. Text sent there is processed on the server rather than in your browser.

```bash
curl -X POST https://api.findutils.com/api/tools/sql-to-json/execute \
  -H "Content-Type: application/json" \
  -d @- <<'EOF'
{"sql": "INSERT INTO users (id, zip) VALUES (1, '02134');", "coerce_numbers": true, "indent": 0}
EOF
```

That returns `[{"id":1,"zip":"02134"}]` in the `json` field. Other arguments: `group_by_table` (`auto`, `always` or `never`), `include_table_key`, `table` and `max_rows`. See the [API reference](/api/sql-to-json/) and the [MCP reference](/mcp/sql-to-json/).

## Tools Used in This Guide

| Tool | Use |
|---|---|
| [SQL to JSON](/convert/sql-to-json/) | Read INSERT statements into typed JSON |
| [SQL to CSV](/convert/sql-to-csv/) | Read the same dumps into CSV for a spreadsheet |
| [JSON to SQL](/convert/json-to-sql/) | Turn JSON rows back into INSERT statements |
| [CSV to SQL](/convert/csv-to-sql/) | Turn a CSV file into INSERT statements |
| [JSON Formatter](/developers/json-formatter/) | Format and validate the JSON you copied |

## FAQ

### How do I convert a MySQL dump to JSON?

Paste the mysqldump output into SQL to JSON. Every table with INSERT rows becomes an array of objects, grouped by table name when there is more than one. No MySQL server is needed.

### Does the tool run my SQL?

No. It reads the statements as text. Functions such as `NOW()` are kept as their SQL text, not evaluated.

### Why is a number in my dump a string in the JSON?

Either it was quoted and would change on the way to a number, like `'007'` or `'1.50'`; or another quoted value in the same column would, and the column stays all strings so it does not mix types; or it is too large for a JSON number to hold exactly, like an ID above 9007199254740991.

### Can it read PostgreSQL COPY blocks?

No. Export with `pg_dump --inserts` or `--column-inserts` so the rows are INSERT statements.

### Is my dump uploaded?

On the page, no. The SQL is parsed in your browser tab.

## Next Steps

Convert your dump with [SQL to JSON](/convert/sql-to-json/). For a spreadsheet instead, use [SQL to CSV](/convert/sql-to-csv/), and read the [SQL to CSV guide](/guides/sql-to-csv/) for the parsing rules the two tools share.
