Как избежать зарезервированных слов, используемых в качестве имен столбцов? MySQL / Создать таблицу

143

Я генерирую таблицы из классов в .NET, и одна проблема заключается в том, что у класса может быть имя поля, keyкоторое является зарезервированным ключевым словом MySQL. Как мне избежать этого в операторе создания таблицы? (Примечание: другая проблема ниже - текст должен быть фиксированного размера, чтобы быть индексированным / уникальным)

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;
Джонатан Леффлер
источник

Ответы:

188

Вы можете использовать двойные кавычки, если включен режим ANSI SQL

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; 

или проприетарный обратный тик, уходящий в противном случае. (Где найти `символ на различных раскладках клавиатуры, описано в этом ответе )

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; 

(Источник: Справочное руководство по MySQL, 9.3 Зарезервированные слова )

Мартин Смит
источник
5
IMHO вы должны всегда указывать все имена полей и имена таблиц.
rjmunro
10
@rjmunro - это несколько более защитный подход, поскольку он защищает вас от новых зарезервированных ключевых слов, вводимых в более поздних версиях, но мне не нравится визуальный беспорядок.
Мартин Смит
То же исправление (двойные кавычки для экранирования) работает и с ключевыми словами в CQL Cassandra. Я знаю, что это немного не по теме, но эта тема всплыла в поиске, посвященном Cassandra.
Годфри Дюк,
Ссылка на справочное руководство MySQL пока не работает. Актуальная ссылка: dev.mysql.com/doc/refman/5.7/en/keywords.html
Miha_x64
73

Вы должны использовать символ обратной галочки (`), например:

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

Если вас интересует переносимость между разными серверами SQL, вам следует использовать запросы ANSI SQL. Экранирование строк в ANSI SQL выполняется с помощью двойных кавычек ("). К сожалению, этот метод экранирования не переносится в MySQL, если он не установлен в режиме совместимости с ANSI.

Лично я всегда запускаю свой сервер MySQL с аргументом --sql-mode = 'ANSI', поскольку это позволяет использовать оба метода для экранирования. Если вы пишете запросы, которые будут выполняться на сервере MySQL, который не был настроен / не контролируется вами, вот что вы можете сделать:

  • Напишите все свои SQL-запросы в ANSI SQL
  • Включите их в следующие запросы MySQL:

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

Таким образом, единственные запросы, специфичные для MySQL, находятся в начале и в конце вашего .sql-скрипта. Если вы хотите отправить их на другой сервер, просто удалите эти 3 запроса, и все готово. Еще более удобно вы могли бы создать сценарий с именем: script_mysql.sql, который будет содержать указанные выше запросы настройки режима, создать сценарий script_ansi.sql и сбросить режим.

Харалампос Серенис
источник
Это круто! Я могу написать запрос один раз и просто переключить стеки MySQL!
ravemir