SQL escape and unescape
Turn text into a string literal MySQL, SQL Server, SQLite or PostgreSQL reads back exactly, or read a literal back into text.
- SECURE
- NO UPLOADS
- NO SIGNUP
- BROWSER BASED
- FREE
- FOREVER.
Support us with a link or a share
Not injection protection — use parameters in code. This is for literals you write yourself.
The result is the complete literal, quotes included.
- Characters in
- —
- Sequences written
- —
- Characters out
- —
Nothing at the counter yet.
A textarea rewrites CRLF to LF. Browsers do it to every form field before a script can read it, so pasted text arrives with 0 CRLF pairs and 0 lone LF whatever you copied. If your line endings matter, open the file instead.
What gets escaped in standard SQL, and why
| Character | Written as | Why |
|---|---|---|
| ' | '' | Ends the literal. Doubling it is the only escape standard SQL has. |
| \, line breaks, tabs | unchanged | A backslash is an ordinary character here, and line breaks and tabs can stand raw inside the quotes. Doubling a backslash would store two. |
| NUL | U+FFFD | No spelling exists. SQLite stops reading the statement at a raw NUL and PostgreSQL text cannot hold one, so it is replaced, and the page says so before the result. |
| % and _ | unchanged | They are only wildcards inside a LIKE pattern, which needs its own ESCAPE clause. In a plain literal they are ordinary characters. |
Unescaping reads doubled quotes and nothing else, the way SQLite does. PostgreSQL follows the same rule with standard_conforming_strings on, its default; that was not measured. A single quote that is not doubled ends the literal, so it is listed with its position and kept as written.
Nothing you type or open here is uploaded, put in the URL, or written to a log. The escaping runs in this tab, with no database connection.
Escaping is not how you stop SQL injection
If a value typed by a user, read from a request or pulled from a file is going into a query
your application runs, do not escape it. Send it as a bound parameter instead:
?, $1 or @name, depending on the driver. The database
then receives the statement and the value separately, and no character in the value can
change what the statement does. Escaping by hand only protects you if every value, in every
query, is escaped with the rules of the exact server, character set and SQL mode it will
reach. Miss one spot, or move to a server configured differently, and the protection is
gone.
There are still honest reasons to write a literal yourself: a migration that inserts a
default setting, a seed file for a test database, a one-off UPDATE typed into a
console, or a fixture copied into documentation. Those are what this tool is for.
What an SQL escape does, and why there is no single answer
A string literal starts and ends with a single quote, so the one character every database
needs escaped is that quote. Standard SQL writes it twice: 'O''Brien' holds the
seven characters of O'Brien. SQLite and PostgreSQL follow that rule and nothing more. A
backslash, a tab or a line break stays exactly as typed, and doubling a backslash there would
store two of them. The SQL escape you need therefore depends on which server reads the
result, which is why the database is the first choice above the text box.
MySQL reads backslashes, and that changes everything
Unless a server runs with NO_BACKSLASH_ESCAPES, MySQL treats a backslash inside a
literal as the start of an escape. A Windows path such as C:\new comes out of
the server with a line feed where the backslash and n were. A value ending in a backslash is
worse: the backslash escapes the closing quote, the literal keeps going, and the rest of the
statement becomes part of the string or a syntax error. So in MySQL mode every backslash is
doubled, and line feeds, carriage returns, tabs, backspace, NUL and U+001A are written as
\n, \r, \t, \b,
\0 and \Z, the same spellings mysqldump uses. Quotes are still
doubled, so the output survives being copied into other tools.
If your server does run NO_BACKSLASH_ESCAPES, choose Standard SQL: that server
reads \\ as two characters. MariaDB documents the same default as MySQL.
SQL Server, the N prefix and a backslash before a line break
For SQL Server the result starts with N. Without it a literal is converted to the
database's code page before it reaches an NVARCHAR column, and letters outside that
code page turn into question marks. Microsoft also documents a quirk that trips up file paths:
a backslash immediately followed by a line break continues the string on the next line, and
both characters disappear from the value. Neither can be escaped inside a single literal, so
the tool closes the literal after the backslash and continues with ' + N'.
NUL and the other characters a literal cannot carry
MySQL stores a NUL character written as \0. The SQLite library stops reading
the statement text at a raw NUL, and PostgreSQL text columns reject U+0000 outright. In
Standard SQL and SQL Server modes a NUL is therefore replaced with U+FFFD, and the count
appears above the result rather than being hidden inside it. When the byte really matters,
build it with char(0) in SQLite or NCHAR(0) in SQL Server and join it
to the surrounding literals.
Reading a literal back into text
Unescape takes the whole literal, quotes and prefix included, and returns the value the
database would store. In MySQL mode it reads every backslash sequence the server defines and
flags the ones MySQL silently simplifies, such as \q becoming q. A quote that
is not doubled is reported with its position, because in a real statement it closes the
string and everything after it would run as SQL. Text without an opening quote is treated as
the inside of a literal.
Carriage returns need a file, not a paste
A browser turns every CR LF pair in a text box into a single LF before any script sees it, so
pasted text cannot tell you anything about Windows line endings. Open the file with the
button instead and its bytes are read unchanged. Clients differ as well: the
sqlite3 shell and the mysql command-line client both turned a raw
CR LF inside a literal into LF when reading SQL from a file in our tests, while the SQLite
library kept it. MySQL mode writes \r, which the mysql client leaves alone. Standard SQL
has no escape for a carriage return, so it stays raw and the tool says so.
What was tested, and what was not
Standard SQL output was read back by SQLite 3.51 and MySQL output by a MySQL 8.4 server, using
more than a hundred generated strings full of quotes, backslashes, NUL, line breaks and emoji.
PostgreSQL and SQL Server were not available to test. Their rules here follow their official
documentation, and this page says so rather than implying otherwise. Identifiers such as
"order", `order` and [order] use a different quote
character, and LIKE patterns add a second layer where % and _ are
wildcards; neither is handled here.
Related SQL and escaping tools
To tidy the query the literal goes into, run it through
the SQL formatter. Turning a whole spreadsheet or API
response into INSERT statements is faster with
CSV to SQL or JSON to SQL, which quote
every value with the same rules as this page. When the text is headed for a JSON payload
instead, use the JSON escaper; for configuration files or markup,
XML escaping and HTML escaping.
Your text stays in this tab
There is no database connection behind this page. Escaping and unescaping are string operations in your browser, nothing you enter is sent or logged, and the address bar never carries your input, so connection strings and customer records are fine to work with here.
Questions
Is escaping strings enough to prevent SQL injection?
No. Parameterized queries are the protection: the driver sends the SQL and the values separately, so a value can never become code. Escaping only works when every value in every query is escaped with the exact rules of the server, connection character set and SQL mode in use, and one forgotten spot is enough. Use this tool for literals you write by hand, such as a migration, a seed file or a query typed into a console.
How do I escape a single quote in SQL?
Write it twice. Inside a string literal, '' stands for one apostrophe, so O'Brien becomes 'O''Brien'. That is the standard SQL rule, and MySQL reads it the same way. MySQL also accepts a backslash before the quote, but a string written that way breaks on a server running NO_BACKSLASH_ESCAPES and in every other database, which is why this tool always doubles.
Why does MySQL need different escaping from PostgreSQL and SQLite?
Because MySQL treats a backslash inside a string as the start of an escape unless the server runs NO_BACKSLASH_ESCAPES. A Windows path such as C:\new then contains a line feed instead of a backslash and an n, and a value that ends in a backslash swallows its own closing quote. PostgreSQL, SQLite and SQL Server read a backslash as an ordinary character, so doubling it there would store two.
Can an SQL string literal contain a NUL character?
In MySQL, yes, written as \0. SQLite stops reading the SQL text at a raw NUL, and PostgreSQL text columns cannot store U+0000 at all, so standard mode and SQL Server replace it with U+FFFD and say so before showing the result. In SQLite you can concatenate char(0), and in SQL Server NCHAR(0), when the byte itself matters.
Does my text or query leave the browser?
No. Escaping and unescaping are string operations performed by this tab, with no database connection and no server involved. Nothing you type or open is added to the address bar or written to a log. Very long inputs are handed to a worker thread started from this page’s own files so that typing stays responsive. Passwords, connection strings and customer data can be pasted safely.