167

I am generating tables from classes in .NET and one problem is a class may have a field name key which is a reserved MySQL keyword. How do I escape it in a create table statement? (Note: The other problem below is text must be a fixed size to be indexed/unique)

create table if not exists misc_info (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
key TEXT UNIQUE NOT NULL,
value TEXT NOT NULL)ENGINE=INNODB;
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

4 Answers4

210

You can use double quotes if ANSI SQL mode is enabled

CREATE TABLE IF NOT EXISTS misc_info
  (
     id    INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
     "key" TEXT UNIQUE NOT NULL,
     value TEXT NOT NULL
  )
ENGINE=INNODB; 

or the proprietary back tick escaping otherwise. (Where to find the ` character on various keyboard layouts is covered in this answer)

CREATE TABLE IF NOT EXISTS misc_info
  (
     id    INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
     `key` TEXT UNIQUE NOT NULL,
     value TEXT NOT NULL
  )
ENGINE=INNODB; 

(Source: MySQL Reference Manual, 9.3 Reserved Words)

Martin Smith
  • 438,706
  • 87
  • 741
  • 845
  • 7
    IMHO you should quote all field names and table names always. – rjmunro Sep 17 '13 at 11:50
  • 16
    @rjmunro - Doing so is somewhat more defensive as it protects you against new reserved keywords being introduced in later versions but I don't like the visual clutter. – Martin Smith Sep 17 '13 at 12:02
  • The same fix (double quote to escape) works for keywords in Cassandra's CQL as well. _A bit off-topic, I know, but this thread surfaced in a Cassandra-specific search._ – Godfrey Duke Feb 26 '16 at 22:44
  • MySQL Reference Manual link is broken for now. Actual link: https://dev.mysql.com/doc/refman/5.7/en/keywords.html – Miha_x64 Dec 09 '17 at 15:56
84

You should use back tick character (`) eg:

create table if not exists misc_info (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
`key` TEXT UNIQUE NOT NULL,
value TEXT NOT NULL)ENGINE=INNODB;
15

If you are interested in portability between different SQL servers you should use ANSI SQL queries. String escaping in ANSI SQL is done by using double quotes ("). Unfortunately, this escaping method is not portable to MySQL, unless it is set in ANSI compatibility mode.

Personally, I always start my MySQL server with the --sql-mode='ANSI' argument since this allows for both methods for escaping. If you are writing queries that are going to be executed in a MySQL server that was not setup / is controlled by you, here is what you can do:

  • Write all you SQL queries in ANSI SQL
  • Enclose them in the following MySQL specific queries:

    SET @OLD_SQL_MODE=@@SQL_MODE;
    SET SESSION SQL_MODE='ANSI';
    -- ANSI SQL queries
    SET SESSION SQL_MODE=@OLD_SQL_MODE;
    

This way the only MySQL specific queries are at the beginning and the end of your .sql script. If you what to ship them for a different server just remove these 3 queries and you're all set. Even more conveniently you could create a script named: script_mysql.sql that would contain the above mode setting queries, source a script_ansi.sql script and reset the mode.

Clement Cherlin
  • 387
  • 6
  • 13
0

For CosmosDB SQL you might want to use

SELECT item["RESERVED_KEY"] FROM ...
TacoEater
  • 2,115
  • 20
  • 22