※この記事にはアフィリエイト広告(プロモーション)が含まれます。
SQL の書き方が MySQL の文法に合わないと、実行する前に次のエラーで止まります。
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order from orders' at line 1
この記事のログは MySQL 8.4.11(Ubuntu 26.04 の標準パッケージ)で採りました。表 orders には列 id と order があります。
まず見る(結論)
near '...'の中身は、MySQL が読めなくなった位置から後ろの SQL。原因はその先頭の語か、その直前にあるnear ''(空)なら、SQL が途中で終わっている。閉じていない括弧・引用符、末尾のカンマ、DELIMITERなしのプロシージャを疑う- 列名や表名が予約語(
order、rank、keyなど)なら、バッククォート`で囲む - 列名をシングルクォート
'で囲むと文字列になる。囲むならバッククォート
near の後ろの読み方
| SQL | near に出た文字列 | 原因 |
|---|---|---|
SELECT id, order FROM orders |
'order from orders' |
予約語 order を列名に使った |
CREATE TABLE t_rank (rank int) |
'rank int)' |
rank は 8.0 から予約語 |
SELECT id, FROM orders |
'from orders' |
FROM の前に余分なカンマ |
SELECT id ORDER BY id FROM orders |
'from orders' |
句の順番が違う(FROM は ORDER BY より前) |
SELCT id FROM orders |
'selct id from orders' |
キーワードのつづり間違い |
INSERT INTO orders (id, 'order') VALUES (1, 10) |
''order') values (1, 10)' |
列名をシングルクォートで囲んだ |
SELECT id FROM orders LIMIT 1+1 |
'+1' |
LIMIT に式は書けない |
... WHERE name = 'a |
''a' |
引用符が閉じていない |
INSERT ... VALUES (1, 10), |
'' |
末尾に余分なカンマ |
CREATE PROCEDURE p1() BEGIN SELECT 1; SELECT 2; END |
'' |
DELIMITER を変えていない |
'from orders' と出た2つの例は、 FROM 自体ではなく、その手前(余分なカンマや句の順番)に原因があります。
長い SQL では at line N も手がかりになります。N は SQL の中での行番号です。
予約語の列名はバッククォートで囲む
CREATE TABLE orders (id int PRIMARY KEY, `order` int, `rank` int, `name` varchar(20));
SELECT id, `order` FROM orders;
どれが予約語かは information_schema.KEYWORDS で引けます。8.4.11 では 262 語が予約語でした。
SELECT word, reserved FROM information_schema.keywords
WHERE word IN ('ORDER','RANK','NAME','KEY','STATUS','GROUPS','LEAD','ROW') ORDER BY word;
| WORD | RESERVED |
| GROUPS | 1 |
| KEY | 1 |
| LEAD | 1 |
| NAME | 0 |
| ORDER | 1 |
| RANK | 1 |
| ROW | 1 |
| STATUS | 0 |
RESERVED が 0 の name や status はキーワードですが、囲まなくても列名に使えます。rank・groups・lead などはウィンドウ関数の追加で 8.0 から予約語になりました。5.7 で作った表や SQL を 8.0 以降に移すと、ここで止まります。
シングルクォート・ダブルクォート・バッククォート
SELECT "order" FROM orders;
| order |
| order |
SELECT `order` FROM orders;
| order |
| 10 |
MySQL の既定では、ダブルクォートで囲んでもシングルクォートと同じく文字列になります。"order" は列ではなく文字列 order になり、エラーにならず、全行に同じ文字列が返ります。標準 SQL のようにダブルクォートで識別子を囲みたい場合は sql_mode に ANSI_QUOTES を加えます。
1064 にならない書き間違い
| SQL | 結果 |
|---|---|
SELECT id FROM orders(id の後ろが全角スペース) |
ERROR 1054 (42S22): Unknown column 'id from' in 'field list' |
SELECT id name FROM orders(カンマ抜け) |
エラーにならない。id に別名 name が付いて1列だけ返る |
SELECT idd FROM orders |
ERROR 1054 (42S22): Unknown column 'idd' in 'field list' |
SELECT id FROM orderz |
ERROR 1146 (42S02): Table 'sdb.orderz' doesn't exist |
全角スペースは空白として扱われず、id from がひとつながりの列名として読まれました。エラーメッセージの中に見慣れない空白があれば全角を疑います。日本語の資料から SQL をコピーしたときに入りやすい文字です。
ストアドプロシージャは DELIMITER を変える
mysql クライアントは ; で SQL を区切ってサーバーに送ります。プロシージャの本体に ; があると、最初の ; までが1つの SQL として送られ、near '' の 1064 になります。区切り文字を一時的に変えてから作ります。
DELIMITER //
CREATE PROCEDURE p1()
BEGIN
SELECT 1;
SELECT 2;
END //
DELIMITER ;
DELIMITER は mysql クライアントのコマンドで、サーバーには送られません。アプリケーションのドライバーから実行するときは、本体ごと1つの文として送れば DELIMITER は要りません。