Skip to content

Markdown Table to SQL Converter

Paste a Markdown table and get CREATE TABLE and INSERT statements for PostgreSQL, MySQL, SQLite or SQL Server, with column types inferred.

Paste a Markdown table

Sample data shown — paste or drop your own to replace it.

Converts as you type. CSV, TSV, HTML and JSON are detected too.
Output
Infers INTEGER, DECIMAL, BOOLEAN and VARCHAR
CREATE TABLE "my_table" (
  "feature" VARCHAR(64),
  "free_tier" VARCHAR(64),
  "pro_12_mo" VARCHAR(64),
  "enterprise" VARCHAR(64)
);

INSERT INTO "my_table" ("feature", "free_tier", "pro_12_mo", "enterprise") VALUES
  ('Unlimited Tables', 'Yes', 'Yes', 'Yes'),
  ('Custom Formatting', 'Basic', 'Advanced', 'Full Suite'),
  ('Team Sharing', 'No', 'Up to 10', 'Unlimited'),
  ('Priority Support', 'Community', '24h SLA', 'Dedicated Rep');
4 rows × 4 columns
Rendered Preview
FeatureFree TierPro ($12/mo)Enterprise
Unlimited TablesYesYesYes
Custom FormattingBasicAdvancedFull Suite
Team SharingNoUp to 10Unlimited
Priority SupportCommunity24h SLADedicated Rep

How to convert a Markdown table to SQL in 3 steps

  1. Paste the Markdown table

    Paste it into the Paste Markdown box (CSV, TSV and HTML tables are detected too), or upload a file. The header row becomes the column names; the first table in the text is used.

  2. Pick the SQL dialect

    The SQL tab on the right is already selected. Choose PostgreSQL, MySQL, SQLite, Microsoft SQL Server or Standard SQL from the SQL dialect list; the types and quoting change with it.

  3. Copy the SQL

    Type your table name in the Table name box above the output, click Copy SQL and run it in your database client, or open Download for table.sql.

Example

Markdown table
| Order ID | Customer | Total | Shipped | Ordered on | Note |
| ---: | :--- | ---: | :---: | :---: | :--- |
| 1042 | Ada O'Neil | 129.50 | yes | 2026-10-02 | |
| 1043 | Sam Wu | 18.00 | no | 2026-10-05 | gift wrap |
| 1044 | Noor Aziz | 310.25 | yes | 2026-10-09 | NULL |
PostgreSQL output
CREATE TABLE "my_table" (
  "order_id" INTEGER,
  "customer" VARCHAR(64),
  "total" NUMERIC(10, 2),
  "shipped" BOOLEAN,
  "ordered_on" DATE,
  "note" VARCHAR(64)
);

INSERT INTO "my_table" ("order_id", "customer", "total", "shipped", "ordered_on", "note") VALUES
  (1042, 'Ada O''Neil', 129.50, TRUE, '2026-10-02', NULL),
  (1043, 'Sam Wu', 18.00, FALSE, '2026-10-05', 'gift wrap'),
  (1044, 'Noor Aziz', 310.25, TRUE, '2026-10-09', NULL);

Options explained

Paste Markdown box
Converts 150 ms after you stop typing, and immediately on paste. The badge shows the detected format. Only the first table in the text is used.
Upload file
Reads a .md, .csv, .tsv, .json, .html, .txt or Excel file from your computer without uploading it anywhere..md · .csv · .tsv · .json · .html · .txt · .xlsx · .xls · .ods
Paste / Sample / Clear
Paste reads the clipboard, Sample loads an example Markdown table, Clear empties the box.
Edit grid / Markdown tabs
Fix cells and rename headers, which become the column names. Undo and redo are available. The Markdown tab shows the source and stays in sync.
Tools
Header case, transpose, and quick or deep clean for stray spaces and blank rows. Header case changes the column names.UPPER · lower · Title Case · Transpose · Quick clean · Deep clean
SQL dialect
Sets the identifier quoting, the column types and the INSERT layout. PostgreSQL, MySQL and SQLite write one multi-row INSERT; SQL Server and Standard SQL write one INSERT per row.PostgreSQL (default) · MySQL · SQLite · Microsoft SQL Server · Standard SQL (ANSI)
Output tabs
This page opens on SQL. The same table can be switched to Markdown, HTML, CSV, TSV, JSON, LaTeX or Jira. The Table name box sets the name (my_table by default, schema.table works too). There is no DROP TABLE option; edit it into the output if you need one.SQL (selected) · Markdown · HTML · CSV · TSV · JSON · LaTeX · Jira
Copy SQL
Copies exactly what the output box shows: the CREATE TABLE statement and the INSERT statements.
Download
Saves the SQL as table.sql, or the table as an Excel workbook (.xlsx), a CSV file or a PNG image..sql · .xlsx · .csv · .png
Copy link
Copies a URL that reopens this table. The table is stored after #md= in the link, which browsers do not send to a server.

Convert Markdown to…

Convert to Markdown from…

Browse all 36 tools

About this tool

Paste a Markdown table and get a CREATE TABLE statement and INSERT statements as you type. Pick PostgreSQL, MySQL, SQLite, Microsoft SQL Server or Standard SQL, and the identifier quoting, column types and INSERT layout follow. Types are inferred from every value in a column: integers, decimals, yyyy-mm-dd dates, true/false/yes/no booleans, otherwise text. Empty cells become NULL and quotes in values are escaped. Type the table name in the Table name box (my_table by default); there are no keys or constraints, so review the types before you run it. Everything runs in your browser.

  • CREATE TABLE plus INSERT statements in one copy
  • Five dialects: PostgreSQL, MySQL, SQLite, SQL Server, ANSI
  • Types inferred from all rows: numbers, dates, booleans, text
  • Quoted identifiers: "x", `x` or [x] per dialect
  • Single quotes in values doubled; MySQL backslashes escaped
  • Empty cells and NULL become SQL NULL
  • Runs in your browser; the table is not uploaded

Technical details

How the SQL is generated

Each column gets a name from its header and a type inferred from every value in that column, then the tool writes CREATE TABLE followed by the INSERT statements, ending in semicolons. It writes DDL and data only: there is no primary key, no NOT NULL and no DROP TABLE, and the table is called my_table unless you type another name in the Table name box.

  • Column names: Headers are lowercased, characters other than letters, digits and _ become _, and the name is quoted. “Order ID” gives "order_id"; a name starting with a digit gets a col_ prefix; duplicates get _2, _3.
  • Types: A column is BOOLEAN if every value is true, false, yes or no; an integer column is INTEGER (BIGINT past 2,147,483,647); other plain numbers are a decimal type; yyyy-mm-dd is DATE; a date with a time is a timestamp; everything else is VARCHAR (TEXT past 255 characters). 1 and 0 alone are not treated as booleans.
  • Decimals: A decimal column is NUMERIC(p, s) or DECIMAL(p, s) sized from the data: s is the most decimal places in any value (at least 2 for money) and p leaves room for the longest whole part, never under 10. 1.5 and 22.125 give (10, 3). SQLite uses REAL.
  • Leading zeros: A column where a value like 02134 appears is kept as text, so zip codes and phone numbers are not turned into numbers.
  • Currency: Values like $1,234.50, €12, 12.50€ and (45.50) are read as numbers: the column becomes DECIMAL and the INSERT writes 1234.50, 12, 12.50 and -45.50, with the symbols and thousands separators removed. A lone comma (1,5) may be a decimal comma, so such a column stays text.
  • Values: Empty cells and the word NULL become NULL. Text is wrapped in single quotes and any single quote inside is doubled; MySQL also doubles backslashes. Booleans are TRUE/FALSE, or 1/0 for MySQL, SQLite and SQL Server.
  • No inline Markdown: <br>, **bold** and links are inserted as typed text.

Tips and best practices

Set the table name before you run it

Type the real table name in the Table name box. Add a PRIMARY KEY or NOT NULL constraints by hand if you need them.

Clean the data first

Type inference looks at every cell. A single stray “n/a” in a number column turns it into VARCHAR, so clear or fix such cells in Edit grid first, or use Tools › Quick clean.

Test on a scratch database

Run the generated SQL on a throwaway database or inside a transaction first. Review the inferred types before using the table for real data.

Common problems and fixes

A price column came out as VARCHAR

Cause: At least one value in the column is not a plain number, for example 1,5 (a possible decimal comma), 50%, “n/a” or text. $129.99 and 1,200.50 are fine.

Fix: Fix or clear that value in Edit grid (or with find and replace), and the column becomes NUMERIC or DECIMAL.

A decimal column is too narrow for new data

Cause: Decimal columns are sized from the values pasted: the scale is the most decimal places seen, and the precision leaves room for the longest whole part (at least 10 digits).

Fix: Change the type in the output, for example NUMERIC(18, 6), before running it, or add a sample row with the largest value.

The statement fails on SQL Server or an old database

Cause: Dialect rules differ: SQL Server writes one INSERT per row, and older databases may not accept every type.

Fix: Pick the matching dialect in the SQL dialect list. For other engines, start from Standard SQL (ANSI) and adjust the types.

A column that should be text became INTEGER

Cause: Every value in it is a plain whole number without leading zeros, such as an ID.

Fix: Change the type in the output, or add a letter prefix to the values.

Platform compatibility

PlatformSupportNotes
PostgreSQL SupportedINTEGER, BIGINT, NUMERIC(p, s), BOOLEAN, DATE, TIMESTAMPTZ, TEXT, VARCHAR; one multi-row INSERT.
MySQL / MariaDB SupportedINT, DECIMAL(p, s), TINYINT(1), DATETIME, backtick quoting; backslashes in text are doubled.
SQLite SupportedINTEGER, REAL and TEXT only, matching SQLite’s type affinity; one multi-row INSERT.
Microsoft SQL Server SupportedINT, DECIMAL(p, s), BIT, DATETIME2, NVARCHAR, [bracket] quoting; one INSERT per row.

Frequently asked questions

How do I convert a Markdown table to SQL?

Paste the Markdown table into the box above. The SQL tab on the right is already selected; choose your database in the SQL dialect list, then click Copy SQL. You get one CREATE TABLE statement followed by the INSERT statements, with the headers as column names.

Which databases are supported?

PostgreSQL (the default), MySQL, SQLite, Microsoft SQL Server and Standard SQL (ANSI). The dialect changes identifier quoting ("x", `x` or [x]), the column types, boolean values and whether the rows go in one multi-row INSERT or one INSERT each.

How are the column types chosen?

From all values in the column. All true/false/yes/no is BOOLEAN, whole numbers are INTEGER (BIGINT when large), other numbers, including $1,234.50 and 1,200, are NUMERIC(p, s) or DECIMAL(p, s) sized from the data, yyyy-mm-dd is DATE, a date with a time is a timestamp, and the rest is VARCHAR, or TEXT past 255 characters.

Can I change the table name?

Yes: type it in the Table name box above the output (the default is my_table; schema.table works too). Characters other than letters, digits and underscores become _. There is no primary key, NOT NULL or DROP TABLE line, so add those by hand if you need them.

Why did my price column become VARCHAR?

Because at least one value is not a plain number, for example 1,5 (it may be a decimal comma), 50% or “n/a”. Prices such as $129.99 and 1,200 are read as numbers, with the symbol and separator removed from the INSERT. Fix the odd value in Edit grid and the column becomes NUMERIC or DECIMAL, with the scale taken from the most decimal places in the data.

How are quotes, NULL and empty cells handled?

Empty cells and the word NULL become NULL. Text is wrapped in single quotes and a single quote inside is doubled, as in the INSERT example above; MySQL also doubles backslashes. Booleans are TRUE/FALSE, or 1/0 for MySQL, SQLite and SQL Server.

Is it safe to run the generated SQL?

The values are escaped as string literals, but you should still read the statements and try them on a scratch database first. The tool only generates text; it never connects to a database, and your table is not uploaded.

What do I do with several tables?

Only the first table in the pasted text is converted. Paste each table separately and set the table name for each.