Erro de sintaxe devido ao uso de uma palavra reservada como nome de tabela ou coluna no MySQL

May 03 2014

Estou tentando executar uma consulta MySQL simples como a seguir:

INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)

Mas estou recebendo o seguinte erro:

ERROR 1064 (42000): você tem um erro na sintaxe do SQL; verifique o manual que corresponde à versão do seu servidor MySQL para a sintaxe correta para usar próximo 'key) VALUES ('Tim', 'Florida', 42)'à linha 1

Como posso corrigir o problema?

Respostas

294 AmalMurali May 03 2014 at 22:29

#O problema

No MySQL, certas palavras como SELECT, INSERT, DELETEetc., são palavras reservadas. Visto que eles têm um significado especial, o MySQL o trata como um erro de sintaxe sempre que você os usa como um nome de tabela, nome de coluna ou outro tipo de identificador - a menos que você coloque o identificador em crases.

Conforme observado nos documentos oficiais, na seção 10.2 Nomes de objeto de esquema (ênfase adicionada):

Certos objetos no MySQL, incluindo banco de dados, tabela, índice, coluna, alias, visão, procedimento armazenado, partição, espaço de tabela e outros nomes de objeto são conhecidos como identificadores .

...

Se um identificador contém caracteres especiais ou é uma palavra reservada , você deve citá-lo sempre que se referir a ele.

...

O caractere de aspas do identificador é o crase (" `"):

Uma lista completa de palavras-chave e palavras reservadas pode ser encontrada na seção 10.3 Palavras-chave e palavras reservadas . Nessa página, as palavras seguidas de "(R)" são palavras reservadas. Algumas palavras reservadas estão listadas abaixo, incluindo muitas que tendem a causar esse problema.

  • ADICIONAR
  • E
  • ANTES
  • POR
  • LIGAR
  • CASO
  • DOENÇA
  • EXCLUIR
  • DESC
  • DESCREVER
  • DE
  • GRUPO
  • NO
  • ÍNDICE
  • INSERIR
  • INTERVALO
  • É
  • CHAVE
  • GOSTAR
  • LIMITE
  • LONGO
  • COMBINE
  • NÃO
  • OPÇÃO
  • OU
  • ORDEM
  • PARTIÇÃO
  • REFERÊNCIAS
  • SELECIONE
  • TABELA
  • PARA
  • ATUALIZAR
  • ONDE

#A solução

Você tem duas opções.

1. Não use palavras reservadas como identificadores

A solução mais simples é simplesmente evitar o uso de palavras reservadas como identificadores. Você provavelmente pode encontrar outro nome razoável para sua coluna que não seja uma palavra reservada.

Fazer isso tem algumas vantagens:

  • Isso elimina a possibilidade de que você ou outro desenvolvedor que usa seu banco de dados escreva acidentalmente um erro de sintaxe por esquecer - ou não saber - que um determinado identificador é uma palavra reservada. Existem muitas palavras reservadas no MySQL e é improvável que a maioria dos desenvolvedores as conheça todas. Ao não usar essas palavras em primeiro lugar, você evita deixar armadilhas para si mesmo ou para futuros desenvolvedores.

  • O meio de citar identificadores difere entre os dialetos SQL. Enquanto o MySQL usa crases para identificar identificadores por padrão, o SQL compatível com ANSI (e de fato MySQL no modo ANSI SQL, como observado aqui ) usa aspas duplas para identificar identificadores. Assim, as consultas que citam identificadores com crases são menos facilmente portáveis ​​para outros dialetos SQL.

Puramente para reduzir o risco de erros futuros, esse é geralmente um curso de ação mais sábio do que repetir o identificador.

2. Use backticks

Se renomear a tabela ou coluna não for possível, envolva o identificador incorreto em crases ( `), conforme descrito na citação anterior de 10.2 Nomes de objeto de esquema .

Um exemplo para demonstrar o uso (retirado de 10.3 Palavras-chave e palavras reservadas ):

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)

Da mesma forma, a consulta da pergunta pode ser corrigida envolvendo a palavra-chave keyem crases, conforme mostrado abaixo:

INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)";               ^   ^