SQL example

How to escape a single quote in SQL

7 min read Updated Oct 2026 Runs in an isolated runtime
Quick answer

Write the quote twice: 'It''s' is the string It's. That is standard SQL and works in every database, in INSERT, WHERE, UPDATE and LIKE. A backslash (\') is not an escape in standard SQL, and double quotes name columns, not strings. In application code, pass the value as a query parameter and don't escape it at all.

A string literal in SQL starts and ends with a single quote, so an apostrophe inside the text, as in O'Brien or It's, would end the string early. The SQL standard solves this one way: two single quotes in a row inside a string stand for one quote character. The sections below use that rule for inserts, filters and LIKE searches, show two ways to build a quote without typing one, and explain why the two habits people bring from other languages, double quotes and backslashes, don't work.

All of this is for SQL you type by hand: scripts, migrations, console queries. When a value comes from a user or from your program, don't escape it and paste it into the SQL text. Use the driver's placeholders (?, $1, :name or @name, depending on the driver) and pass the value separately. The database then receives the text as data, quotes and all, so there is nothing to escape and no way for the value to change the query.

The examples run on SQLite; the table in section 6 gives the PostgreSQL, MySQL and SQL Server forms. Hit Run on any of them, then edit the code and run it again.

1Double it: 'It''s'Recommended

Inside a single-quoted string, write every apostrophe as two: 'O''Brien'. The database stores one quote, so the value is seven characters long, not eight. A string with several apostrophes doubles each one. The rule is the same wherever a string literal appears: the VALUES list of an INSERT (here a multi-row insert), a WHERE comparison, or the new value in an UPDATE.

double-quote.sql

Output

The table shows O'Brien with a length of 7 and Rock 'n' Roll Diner with 19: each pair became a single character. The WHERE filter finds id 1, and the update stores Smith's Bakery. Doubling works in SQLite, PostgreSQL, MySQL, SQL Server and Oracle alike, so it is the form to use in scripts that must run on more than one of them.

2Search for a quote with LIKE '%''%'

A LIKE pattern is an ordinary string literal, so the apostrophe in it is doubled too: '%''%' means "anything, a quote, anything". The quote isn't a wildcard, so it needs no ESCAPE clause. To get the position of the quote instead, pass instr() the four-character literal '''': an opening quote, a doubled quote, a closing quote, which is a string holding just '.

like-quote.sql

Output

The first query returns the three names with an apostrophe and skips Rain Jacket. The '%''s %' pattern drops Kids' Shoes, whose quote isn't followed by s, and keeps Men's Socks and Women's Hat. instr() reports the quote at positions 5, 4 and 6, counting from 1. SQL Server and MySQL spell it CHARINDEX and INSTR, PostgreSQL strpos; the LIKE pattern itself is the same everywhere.

3Build a quote with char(39), escape text with replace()

char(39) returns the character with code 39, which is the single quote, so you can concatenate one into a string without typing it. That helps when the SQL is itself inside a quoted string somewhere and the doubled quotes start to pile up. Going the other way, replace(text, '''', '''''') doubles every quote in a value, which is how you turn stored text into a literal for a script you generate. SQLite's quote() does that and adds the outer quotes.

char39.sql

Output

The inserted row reads It's done, and same is 1: char(39) and '''' are the same one-character string. replace() gives It''s done, and quote() builds the whole statement INSERT INTO notes VALUES ('It''s done');, ready to run. SQL Server and MySQL also call the function CHAR(39); PostgreSQL calls it chr(39). Generating SQL text like this is fine for scripts and exports, but don't use it to put user input into a query; that is what parameters are for.

4Double quotes are for identifiers, not strings

In standard SQL, double quotes wrap a name: a table or column that is a reserved word, contains a space or needs its exact case. "order" is the column named order, not the text order. So "It's" doesn't sidestep the apostrophe problem; it asks for a column called It's. The second query below shows the quiet way this goes wrong: "note" matches a column name, so the filter compares the column with itself.

double-quotes.sql

Output

The quoted names work, and WHERE note = "note" returns both rows, although no row holds the text note. The last query stops with no such column: "no rush" - should this be a string literal in single-quotes?. SQLite has a legacy quirk here: when a double-quoted name matches no column, the library falls back to treating it as a string literal, so in an app that uses SQLite with its default build settings, or an older sqlite3 shell, that query would quietly return the no rush row. The SQLite on this page has the fallback turned off, as the sqlite3 command-line shell has since version 3.41, so you see the error. Don't rely on the fallback: it turns into the self-comparison above as soon as someone adds a column with that name. PostgreSQL and SQL Server reject double-quoted strings; MySQL accepts them unless ANSI_QUOTES is on (see section 6).

5A backslash is not an escape in standard SQL

Most programming languages escape a quote with a backslash, and MySQL does too by default, which is why \' is a common guess. Standard SQL has no backslash escapes: inside '...' a backslash is an ordinary character and stays as typed. That makes Windows paths and regular expressions easy to write, but it means \n is two characters, not a newline, and 'It\'s' is a syntax error.

backslash.sql

Output

'a\b' prints a\b with a length of 3, and the path keeps both backslashes. 'a\n' is three characters, while 'a' || char(10) is two: the letter and a real newline. The last line fails with unrecognized token: "' AS s;": the string 'It\' ended at the second quote, and the leftover s' AS s; opens a string that never closes. PostgreSQL behaves the same way for plain strings and only reads backslash escapes inside E'...'; SQL Server never does. In MySQL, 'a\b' means something else, so write 'a\\b' there for a literal backslash.

6Other databases

Doubling the quote works everywhere, so it is the safe choice. Each database also has its own alternatives, which you will see in existing code; every form below was run on PostgreSQL 18, MySQL 8.4 and SQL Server (Babelfish). Oracle doubles quotes the same way and also has an alternative quoting syntax, q'[It's]'.

SyntaxDatabaseNotes
'It''s'AllStandard SQL: SQLite, PostgreSQL, MySQL and SQL Server all return It's
E'It\'s'PostgreSQLEscape string: backslash escapes work only inside E'...'; a plain 'a\b' stays as typed
$$It's$$PostgreSQLDollar quoting: nothing inside needs escaping; use $q$...$q$ if the text contains $$
'It\'s'MySQLBackslash escapes are on by default (off with NO_BACKSLASH_ESCAPES); write 'a\\b' for a backslash
"It's"MySQLDouble quotes make a string by default; with ANSI_QUOTES on they name a column
N'It''s'SQL ServerN marks a Unicode (nvarchar) literal; the quote inside is still doubled
chr(39)PostgreSQLPostgreSQL's name for char(39); SQL Server and MySQL use CHAR(39)
QUOTENAME(s, '''')SQL ServerWraps s in quotes and doubles the ones inside, like SQLite's quote()

Frequently asked questions

How do I insert a value that contains an apostrophe in SQL?

Double the apostrophe inside the string: INSERT INTO customers (name) VALUES ('O''Brien'); stores O'Brien, seven characters. This works in SQLite, PostgreSQL, MySQL, SQL Server and Oracle. If the value comes from your program, pass it as a query parameter instead and don't escape it.

How do I search for a single quote with LIKE?

Double it inside the pattern like any other string: WHERE name LIKE '%''%' finds every value that contains an apostrophe. The quote is not a LIKE wildcard, so no ESCAPE clause is needed. instr(name, '''') > 0 (CHARINDEX in SQL Server, strpos in PostgreSQL) does the same check.

Why does \' not escape a quote in SQL?

Standard SQL has no backslash escapes, so in SQLite, PostgreSQL (plain strings) and SQL Server 'a\b' is three characters and 'It\'s' ends at the second quote, which is a syntax error. MySQL is the exception: it reads backslash escapes by default, unless the NO_BACKSLASH_ESCAPES SQL mode is on. PostgreSQL reads them only in E'...' strings.

What is the difference between single and double quotes in SQL?

Single quotes make a string value; double quotes name a table or column, such as "order" for a reserved word. WHERE note = "note" therefore compares the column with itself and matches every row. MySQL treats double quotes as strings unless ANSI_QUOTES is on, and some SQLite builds fall back to a string when no column matches, but neither is portable.

How do I insert text with single quotes in PostgreSQL?

Double them, 'It''s', or use dollar quoting, $$It's$$, where nothing inside needs escaping (use a tag such as $q$...$q$ if the text contains $$). E'It\'s' also works, because backslash escapes are read inside E'...' strings.

How do I escape a single quote in SQL Server?

Double it: 'It''s', or N'It''s' for an nvarchar (Unicode) value; the N prefix doesn't change the escaping. CHAR(39) returns a quote, and QUOTENAME(s, '''') wraps a value in quotes with the inner ones doubled, which is handy in dynamic SQL. Better still, pass values to sp_executesql as parameters.

Run it yourself

Open any of these in the full SQLite editor to tweak, run and share.

SQLite playground