ある日、業務上の必要に応じて不要なデータを削除していたところ、DELETE文を実行するとエラーが発生しました!
著者: Lin Jinghua、オープンソース データベース テクノロジの愛好家、MySQL と Redis の運用と保守が得意
Aikeson オープン ソース コミュニティによって作成されています。オリジナルのコンテンツを許可なく使用することはできません。転載する場合は編集者に連絡し、出典を示してください。
この記事は約 650 文字で構成されており、読むのに 2 分かかると予想されます。
背景
ある日、業務要件に従って不要なデータを削除していたところ、DELETE ステートメントを実行するとエラーが発生しました (MySQL データベース バージョン 5.7.34)。
mysql> delete from test1 t1 where not exists (select 1 from test2 t2 where t1.id=t2.id);
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 't1 where not exists (select 1 from test2 t2 where t1.id=t2.id)' at line 1
これは少し奇妙です。delete ステートメントを実行する前に、同じ条件で SELECT ステートメントを実行しましたが、 を に置き換えました。結局のところ、select *
このdelete
構文エラーの原因は通常、キーワードのスペル ミスまたは中国語記号の存在です。
上記の理由を除外した後、ステートメント自体のロジックから調査することになりますが、DELETE ステートメントがnot exists
この書き方をサポートしていない可能性はありますか? この制限についてはこれまで聞いたことがないと思います。文法エラーの理由から始めて、公式ドキュメントをチェックして答えが見つかるかどうかを確認しましょう。
分析する
DELETE の構文は次のとおりです。
5.7 単一テーブルの削除形式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
以下を注意深く比較した結果、いくつかのヒントが見つかりました。ここの文法ではテーブル名の別名の使用法が記述されていません。別名を使用しているためでしょうか?
mysql> delete from test1 where not exists (select 1 from test2 where test1.id=test2.id);
Query OK, 1 row affected (0.00 sec)
テストの結果、エイリアスは削除され、実行は成功しましたが、以前はデータを削除するときにエイリアスが使用されていたような印象があったため、引き続きドキュメントを調べて確認しました。
さまざまな場所とさまざまなバージョンの形式の違いを比較した後、ようやく問題の原因がわかりました。バージョンが異なると、さらには状況が異なると違いがあります。
8.0 単一テーブルの削除形式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [[AS] tbl_alias]
[PARTITION (partition_name [, partition_name] ...)]
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
5.7 および 8.0 の複数テーブル削除形式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
tbl_name[.*] [, tbl_name[.*]] ...
FROM table_references
[WHERE where_condition]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
FROM tbl_name[.*] [, tbl_name[.*]] ...
USING table_references
[WHERE where_condition]
上記の構文の比較により、5.7 の単一テーブルの削除ではエイリアスの使用がサポートされていませんが、複数のテーブルの削除では (table_references
エイリアスの使用を含む) サポートされていることがわかりました。
また、8.0.16 以降では、単一テーブルの削除でエイリアスの使用がすでにサポートされています。
SQL 標準および他の RDBMS との一貫性を保つために、テーブル エイリアスが単一テーブルおよび複数テーブルの DELETE ステートメントでサポートされるようになりました。(バグ #27455809)
結論は
- MySQL 5.7 で単一のテーブル削除ステートメントを使用する場合、エイリアスは使用できませんが、エイリアスを使用して複数のテーブルを削除できます。
- MySQL 8.0.16 以降では、単一テーブルと複数テーブルでエイリアスを使用できるようになりました。
さらに技術的な記事については、https: //opensource.actionsky.com/をご覧ください。
SQLEについて
SQLE は、開発環境から運用環境までの SQL 監査と管理をカバーする包括的な SQL 品質管理プラットフォームです。主流のオープンソース、商用および国内データベースをサポートし、開発、運用および保守のためのプロセス自動化機能を提供し、オンライン効率を向上させ、データ品質を向上させます。
SQL取得
タイプ | 住所 |
---|---|
リポジトリ | https://github.com/actiontech/sqle |
書類 | https://actiontech.github.io/sqle-docs/ |
リリースニュース | https://github.com/actiontech/sqle/releases |
データ監査プラグイン開発ドキュメント | https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse |