MySQL ERROR 1064: SQLシンタックスエラーの修正方法

beginner🗄️ MySQL2026-03-21| MySQL 5.7, 8.0 / MariaDB / Linux, macOS, Windows / MySQL CLI, phpMyAdmin, DBeaver

Error Message

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 '...' at line 1
#mysql#sql#シンタックスエラー#クエリ#デバッグ

何が起きているのか

クエリが実行されませんでした。MySQLが ERROR 1064 (42000): You have an error in your SQL syntax をスローしました — これは「構文を解析できなかった」というMySQLの汎用的なエラーメッセージです。ステートメントのどこかがMySQLのパーサーが期待する文法規則を違反しています。

よくある誤解として、エラーが指す位置はMySQLが混乱した直後であり、実際のミスがある場所ではありません。つまり「near '...' at line 1」はヒントであって、犯人の自白ではありません。本当の問題は通常、その1トークン前にあります。

ERROR 1064が発生するよくあるシナリオ

  • バッククォートなしでテーブル名やカラム名に予約キーワードを使用している
  • カンマ、括弧、またはクォートの欠落や位置ずれ
  • クォートスタイルの誤り — WordやGoogle Docsの波括弧クォートを直線クォートの代わりに使用している
  • MySQL 5.7サーバーでMySQL 8.0の構文を実行している(またはその逆)
  • ドキュメントエディタからSQLを貼り付けた際に不可視のUnicode文字が混入している
  • UPDATE文で SET キーワードを忘れている
  • ストアドプロシージャ内でセミコロンが余分または不足している

原因別の修正方法

1. 識別子として使われた予約キーワード

これが最も多い原因です。orderkeyvaluerankgroupdescstatus などの名前は予約語です。クォートなしで登場した瞬間にMySQLはエラーを起こします。

-- 失敗
SELECT order, status FROM users;

-- 修正: 予約語をバッククォートで囲む
SELECT `order`, `status` FROM users;

完全なリストは MySQL 8.0 Reserved Words にあります。ブックマークしておくと便利です。

2. クォートの不一致または欠落

-- 失敗: 閉じクォートがない
SELECT * FROM products WHERE name = 'Widget;

-- 失敗: ドキュメントエディタからコピーした波括弧クォート
SELECT * FROM products WHERE name = 'Widget';

-- 修正
SELECT * FROM products WHERE name = 'Widget';

PDFやドキュメントからSQLをコピーしましたか?ターミナルでクォートを手入力し直してください。波括弧クォートは画面上では同じに見えますが、全く異なる文字です。

3. カラム間のカンマ欠落

-- 失敗
SELECT id name email FROM users;

-- 修正
SELECT id, name, email FROM users;

4. UPDATEの構文誤り — SETがない

-- 失敗
UPDATE users name = 'Alice' WHERE id = 1;

-- 修正
UPDATE users SET name = 'Alice' WHERE id = 1;

5. INSERTの括弧構造が間違っている

-- 失敗
INSERT INTO users (id, name) VALUES 1, 'Alice';

-- 修正
INSERT INTO users (id, name) VALUES (1, 'Alice');

6. MySQL 5.7でMySQL 8.0のウィンドウ関数を使用している

-- MySQL 5.7では失敗 — ウィンドウ関数がサポートされていない
SELECT id, ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
FROM employees;

-- まずサーバーバージョンを確認する
SELECT VERSION();

MySQL 5.7のままでウィンドウ関数が必要ですか?MySQL 8.0にアップグレードするか、サブクエリを使ってロジックを書き直してください。

7. ストアドプロシージャでDELIMITERの変更を忘れている

mysql CLIは ; を入力の終わりとして扱います。プロシージャ本体の中で ; に当たると、CLIはすぐに壊れた不完全なステートメントを送信してしまいます。

-- 失敗: CLIが最初の ; で実行してしまう
CREATE PROCEDURE get_users()
BEGIN
  SELECT * FROM users;
END;

-- 修正
DELIMITER //
CREATE PROCEDURE get_users()
BEGIN
  SELECT * FROM users;
END //
DELIMITER ;

デバッグのアプローチ

エラーメッセージが明確でない場合は、ステップごとに絞り込んでいきます。

ステップ1 — "near"のヒントを文字通り読む

MySQLはパーサーが諦めたトークンを示します。実際のミスはほぼ常にそのトークンの直前にあります。

ERROR 1064 (42000): ... near 'WHERE id = 1' at line 1

パーサーは WHERE でエラーになっています。これはその前の句、つまり SET 句が間違っている可能性を示しています。

ステップ2 — クエリを最小限に削ぎ落とす

骨格だけを残して他を全て削除します。句を1つずつ追加して再びエラーになるまで繰り返します。エラーを引き起こした最後の追加部分が原因です。

-- ここから始める
SELECT * FROM users;

-- WHEREを追加
SELECT * FROM users WHERE id = 1;

-- 残りを追加
SELECT * FROM users WHERE id = 1 ORDER BY name;

ステップ3 — 不可視文字を探す

ブラウザやドキュメントエディタから貼り付けたSQLには、ゼロ幅スペース、ノーブレークスペース、Windowsの改行コードなど隠れたUnicodeが含まれていることがあります。見えませんが、パーサーを壊します。

cat -A query.sql | head -5
# ^M(Windowsの改行コード)やその他の予期しない文字を探す

または、ファイルを vim で開いて :set list を実行すると全ての隠し文字が表示されます。

ステップ4 — 実行せずに構文を検証する

# MySQL CLI: EXPLAINで構文エラーを検出する
mysql -u root -p -e "EXPLAIN SELECT * FROM users WHERE id = 1"

# またはmysqlcheckでデータベース全体を確認する
mysqlcheck -u root -p --check mydb

再発防止策

迷ったらテーブル名とカラム名を常にバッククォートで囲む

CREATE TABLE `order` (
  `id` INT PRIMARY KEY,
  `status` VARCHAR(50),
  `value` DECIMAL(10,2)
);

エディタでSQLリンターを使用する

SQLTools(VS Code)や sql-language-server などの拡張機能は、実行する前に構文エラーをフラグします。実行時ではなく記述時に問題を検出できます。

アプリケーションコードでパラメータ化クエリを使用する

文字列の連結でSQLを構築することが、インジェクションバグと構文エラーの両方の原因になります。プリペアドステートメントを使えば両方の問題を一度に解決できます:

# Python (mysql-connector)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
// Node.js (mysql2)
connection.execute('SELECT * FROM users WHERE id = ?', [userId])

修正が成功したか確認する

もう一度クエリを実行します。結果セットまたは Query OK, N rows affected が表示されれば構文エラーは解消されています。

-- SELECTの場合
SELECT id, name FROM users WHERE id = 1;
-- 期待結果: 1行が返される

-- INSERT/UPDATE/DELETEの場合
UPDATE users SET name = 'Alice' WHERE id = 1;
-- 期待結果: Query OK, 1 row affected

ストアドプロシージャを修正しましたか?作成直後に呼び出して、最後まで正常に実行されることを確認してください:

CALL get_users();

Related Error Notes