Erreur de syntaxe due à l'utilisation d'un mot réservé comme nom de table ou de colonne dans MySQL
J'essaie d'exécuter une simple requête MySQL comme ci-dessous:
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
Mais j'obtiens l'erreur suivante:
ERREUR 1064 (42000): vous avez une erreur dans votre syntaxe SQL; vérifiez le manuel qui correspond à votre version de serveur MySQL pour la bonne syntaxe à utiliser près
'key) VALUES ('Tim', 'Florida', 42)'
de la ligne 1
Comment puis-je résoudre le problème?
Réponses
#Le problème
En MySQL, certains mots comme SELECT
, INSERT
, DELETE
etc. sont des mots réservés. Puisqu'ils ont une signification particulière, MySQL le traite comme une erreur de syntaxe chaque fois que vous les utilisez comme nom de table, nom de colonne ou autre type d'identifiant - à moins que vous n'entouriez l'identificateur avec des contre-indications.
Comme indiqué dans la documentation officielle, dans la section 10.2 Noms des objets de schéma (emphase ajoutée):
Certains objets dans MySQL, y compris la base de données, la table, l'index, la colonne, l'alias, la vue, la procédure stockée, la partition, l'espace de table et d'autres noms d'objet sont appelés identificateurs .
...
Si un identifiant contient des caractères spéciaux ou est un mot réservé , vous devez le citer chaque fois que vous y faites référence.
...
Le caractère de guillemet identifiant est le backtick ("
`
"):
Une liste complète des mots clés et des mots réservés se trouve dans la section 10.3 Mots clés et mots réservés . Dans cette page, les mots suivis de "(R)" sont des mots réservés. Certains mots réservés sont répertoriés ci-dessous, y compris plusieurs qui ont tendance à causer ce problème.
- AJOUTER
- ET
- AVANT
- PAR
- APPEL
- CAS
- ÉTAT
- SUPPRIMER
- DESC
- DÉCRIS
- DE
- GROUPE
- DANS
- INDICE
- INSÉRER
- INTERVALLE
- EST
- CLÉ
- COMME
- LIMITE
- LONGUE
- RENCONTRE
- NE PAS
- OPTION
- OU
- ORDRE
- CLOISON
- RÉFÉRENCES
- SÉLECTIONNER
- TABLE
- À
- MISE À JOUR
- OÙ
#La solution
Vous avez deux options.
1. N'utilisez pas de mots réservés comme identifiants
La solution la plus simple est simplement d'éviter d'utiliser des mots réservés comme identifiants. Vous pouvez probablement trouver un autre nom raisonnable pour votre colonne qui n'est pas un mot réservé.
Faire cela présente quelques avantages:
Cela élimine la possibilité que vous ou un autre développeur utilisant votre base de données écrive accidentellement une erreur de syntaxe en oubliant - ou en ignorant - qu'un identifiant particulier est un mot réservé. Il existe de nombreux mots réservés dans MySQL et il est peu probable que la plupart des développeurs les connaissent tous. En n'utilisant pas ces mots en premier lieu, vous évitez de laisser des pièges à vous-même ou aux futurs développeurs.
Le moyen de citer les identificateurs diffère selon les dialectes SQL. Alors que MySQL utilise par défaut des guillemets pour citer les identifiants, SQL conforme à ANSI (et en fait MySQL en mode ANSI SQL, comme indiqué ici ) utilise des guillemets pour citer les identifiants. En tant que telles, les requêtes qui citent des identificateurs avec des accents inversés sont moins facilement transférables vers d'autres dialectes SQL.
Dans le seul but de réduire le risque d'erreurs futures, il s'agit généralement d'un plan d'action plus judicieux que le backtick-citer l'identifiant.
2. Utilisez des backticks
Si le changement de nom de la table ou de la colonne n'est pas possible, encapsulez l'identificateur incriminé dans les backticks ( `
) comme décrit dans la citation précédente de 10.2 Schema Object Names .
Un exemple pour démontrer l'utilisation (tiré de 10.3 Mots clés et mots réservés ):
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)
De même, la requête de la question peut être corrigée en enveloppant le mot-clé key
dans des crochets, comme indiqué ci-dessous:
INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)"; ^ ^