Синтаксическая ошибка из-за использования зарезервированного слова в качестве имени таблицы или столбца в MySQL
Я пытаюсь выполнить простой запрос MySQL, как показано ниже:
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
Но я получаю следующую ошибку:
ОШИБКА 1064 (42000): у вас ошибка в синтаксисе SQL; проверьте руководство, которое соответствует вашей версии сервера MySQL для правильного синтаксиса для использования рядом
'key) VALUES ('Tim', 'Florida', 42)'
в строке 1
Как я могу исправить проблему?
1 ответ
Эта проблема
В MySQL некоторые слова, такие как SELECT
, INSERT
, DELETE
и т.д. являются зарезервированными словами. Поскольку они имеют особое значение, MySQL рассматривает его как синтаксическую ошибку всякий раз, когда вы используете их в качестве имени таблицы, имени столбца или другого типа идентификатора - если только вы не окружите идентификатор обратными метками.
Как отмечено в официальных документах, в разделе 10.2 Имена объектов схемы (выделение добавлено):
Некоторые объекты в MySQL, включая базу данных, таблицу, индекс, столбец, псевдоним, представление, хранимую процедуру, раздел, табличное пространство и другие имена объектов, называются идентификаторами.
...
Если идентификатор содержит специальные символы или является зарезервированным словом, вы должны заключать его в кавычки при каждом обращении к нему.
...
Символом кавычки идентификатора является обратный удар ("
`
"):
Полный список ключевых слов и зарезервированных слов можно найти в разделе 10.3 Ключевые слова и зарезервированные слова. На этой странице слова, за которыми следует "(R)", являются зарезервированными словами. Некоторые зарезервированные слова перечислены ниже, в том числе многие, которые имеют тенденцию вызывать эту проблему.
- ДОБАВЛЯТЬ
- А ТАКЖЕ
- ДО
- ОТ
- ВЫЗОВ
- ДЕЛО
- СОСТОЯНИЕ
- УДАЛЯТЬ
- DESC
- ОПИСАНИЯ
- ОТ
- GROUP
- В
- ИНДЕКС
- ВСТАВИТЬ
- ИНТЕРВАЛ
- ЯВЛЯЕТСЯ
- KEY
- ЛАЙК
- ПРЕДЕЛ
- ДОЛГО
- МАТЧ
- НЕ
- ВАРИАНТ
- ИЛИ ЖЕ
- ПОРЯДОК
- PARTITION
- РЕКОМЕНДАЦИИ
- ВЫБРАТЬ
- ТАБЛИЦА
- К
- ОБНОВИТЬ
- ГДЕ
Решение
У вас есть два варианта.
1. Не используйте зарезервированные слова в качестве идентификаторов
Самое простое решение - просто избегать использования зарезервированных слов в качестве идентификаторов. Вероятно, вы можете найти другое разумное имя для вашей колонки, которое не является зарезервированным словом.
Делать это имеет пару преимуществ:
Это исключает возможность того, что вы или другой разработчик, использующий вашу базу данных, случайно напишут синтаксическую ошибку из-за того, что забыли или не знаете, что конкретный идентификатор является зарезервированным словом. В MySQL есть много зарезервированных слов, и большинство разработчиков вряд ли знают их все. Не используя эти слова в первую очередь, вы не оставляете ловушки для себя или будущих разработчиков.
Средство цитирования идентификаторов отличается в разных диалектах SQL. В то время как MySQL использует кавычки для цитирования идентификаторов по умолчанию, ANSI-совместимый SQL (и, действительно, MySQL в режиме ANSI SQL, как отмечено здесь) использует двойные кавычки для цитирования идентификаторов. Таким образом, запросы, заключающие идентификаторы в кавычки, менее легко переносимы на другие диалекты SQL.
Чисто ради уменьшения вероятности ошибок в будущем, это, как правило, более разумный курс действий, чем обратная кавычка идентификатора.
2. Используйте галочки
Если переименование таблицы или столбца невозможно, оберните ошибочный идентификатор в кавычки (`
), как описано в предыдущей цитате из 10.2 Имена объектов схемы.
Пример, демонстрирующий использование (взято из 10.3 Ключевые слова и зарезервированные слова):
mysql> CREATE TABLE interval (begin INT, end INT); ERROR 1064 (42000): You have an error in your SQL syntax. near 'interval (begin INT, end INT)' mysql> CREATE TABLE `interval` (begin INT, end INT); Query OK, 0 rows affected (0.01 sec)
Аналогично, запрос из вопроса можно исправить, обернув ключевое слово key
в кавычках, как показано ниже:
INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)"; ^ ^