私は次のように簡単なMySQLクエリを実行しようとしています:
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
しかし、次のエラーが表示されます。
エラー1064(42000):SQL構文にエラーがあります。行1で
'key) VALUES ('Tim', 'Florida', 42)'
の近くで使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください。
どうすれば問題を修正できますか?
MySQLでは、SELECT
、INSERT
、DELETE
などの特定の単語は予約語です。それらは特別な意味を持っているため、テーブル名、列名、またはその他の種類の識別子として使用するときは常に、MySQLは構文エラーとして扱います-識別子をバッククォートで囲む場合を除きます。
公式ドキュメントのセクションで 10.2スキーマオブジェクト名 (強調が追加されました):
データベース、テーブル、インデックス、カラム、エイリアス、ビュー、ストアドプロシージャ、パーティション、テーブルスペース、およびその他のオブジェクト名を含むMySQL内の特定のオブジェクトは、identifiers。
...
識別子に特殊文字が含まれている場合、または予約語の場合、must引用するたびにそれを参照してください。
...
識別子の引用文字は、backtick( "
`
"):
キーワードと予約語の完全なリストは、セクション 10.3キーワードと予約語 にあります。そのページでは、「(R)」が後に続く単語は予約語です。この問題を引き起こす傾向がある多くを含むいくつかの予約語は下記にリストされています。
2つのオプションがあります。
最も簡単な解決策は、予約語を識別子として使用しないようにすることです。おそらく、予約語ではない別の適切な列名を見つけることができます。
これを行うことには、いくつかの利点があります。
特定の識別子が予約語であることを忘れている、または知らないために、データベースを使用している開発者または別の開発者が誤って構文エラーを書き込む可能性を排除します。 MySQLには多くの予約語があり、ほとんどの開発者はそれらのすべてを知ることはまずありません。そもそもこれらの言葉を使わないことで、自分自身や将来の開発者にわなをかけないようにできます。
識別子を引用する方法は、SQLダイアレクトによって異なります。 MySQLはデフォルトで識別子の引用にバックティックを使用しますが、ANSI準拠のSQL(および実際には here のようにANSI SQLモードのMySQL)は識別子の引用に二重引用符を使用します。そのため、バッククォートで識別子を引用するクエリは、他のSQLダイアレクトへの移植が容易ではありません。
純粋に将来のミスのリスクを減らすために、これは通常、識別子をバッククォートで引用するよりも賢明なアクションです。
テーブルまたは列の名前を変更できない場合は、 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)"; ^ ^