0
2
意見交換したいこと
SQL の SELECT 文のカラムエイリアスは、必ずバッククォートで括るべきなのでしょうか?
個人的には予約後とカラムエイリアスが衝突している場合のみ、バッククォートで括れば良いのではと思うのですが、バッククォートで括ることをルール化しているという話を聞いて気になった次第です。
使用している DBMS は MySQL8.0 とします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
回答5件
#1
総合スコア4441
投稿2023/11/23 12:17
そもそもカラム等の識別子の名前をバッククォート (`…`) で囲むというのはMySQL独自のルールです。標準SQLではダブルクォート ("…") で囲みますし、MySQLでもANSIモードが無効でなければそのようにできます。
ユーザ定義の識別子と予約語が衝突する事態を避けるために上記の区切り記号で囲むことを義務づけるコーディング規約を採用する場合はあるでしょうし、採用するDBMSがMySQLなどに決まっているのならバッククォートを義務付けることもよくあると思います。
#2
総合スコア86595
投稿2023/11/23 17:19
編集2023/11/24 01:34個人的には予約後とカラムエイリアスが衝突している場合のみ、バッククォートで括れば良いのではと思うのですが、バッククォートで括ることをルール化しているという話を聞いて気になった次第です。
すべての予約語を暗記していない人が参加しているかもしれないプロジェクトなら、一律引用符で括るというルールにするのは、余計な手戻りを防ぐために有効かもしれません。プログラム中のSQLを静的に文法チェックする機能があるIDEで開発していれば不要でしょうが、実行しないとエラーに気づかない環境では有効かと。また、プロジェクトの途中でそういうIDE機能を使い出した場合でも途中でルールを変えると混乱するので変えないでしょうね。
もしくはプロジェクトごとにルールを定めず、全社で統一のルールにするとかも。
一般のプログラミング言語の場合でも、「演算子の順序を把握していない人がいる(かもしれない?)ので、冗長な括弧を付ける」というルールもあるようですね。
x==0 || x>=10 && x<20みたいなのか。a + b * c はさすがに要らないでしょうが。
#3
総合スコア118405
投稿2023/11/24 00:22
予約後(語)とカラムエイリアスが衝突している場合のみ、バッククォートで括れば良いのではと思う
むしろそんな面倒なことをスルくらいなら「予約語を絶対につかわない」というルールにすればいいだけですね。バッククォートは保険ですからかけておいて損はないですし、かけ忘れたときにこそ事故は起こりやすいので厳密な運用にしたほうがむしろ何も考えずに済むので楽だと思います
#4
総合スコア4441
投稿2023/11/24 09:35
編集2023/11/25 00:21補足します。
他の回答でも述べられていますが、全ての予約語をおぼえている人ばかりではありません (というか私はおぼえていない)。
一方、SQL文で特別な意味を持つ語 (キーワード) が必ず予約語であるとも限りません。例えばBEGINやENDは予約語ではありません。予約語を含むMySQLのキーワードはこのくらいあります。予約語あてクイズが作れそう。
また、ある語が予約語か否かは実装によって異なる場合があります。例えばPostgreSQLではALTER, BEFORE, CASCADE, DATABASE, DOUBLE, DUAL, …などは予約語とされていませんがMySQLでは予約語です (PostgreSQL 15.4、MySQL 8.0で確認)。一方例えばDATEはMySQL、PostgreSQLでは予約語ではないですがOracleなどでは予約語です。
これらの違いはシステム間での移植作業などの際に問題になりえます。
さらに、組み込み関数名は予約語ではないですが特殊な扱いを受けることがあります。下記は標準SQLでは文法違反となります (MySQLでもANSIモードが無効になっていなければそうなります)。
CREATE TABLE count (col int);
テーブルの作成に集約関数が出てくるわけがないので、何が間違っているのか一瞬気づかない人もいるかもしれませんね。MySQLの場合は引用符で囲めばcountというテーブルも問題なく作れます。
CREATE TABLE `count` (col int);
ところが次の文は文法的に正しいです。COUNTは予約語ではないので。
SELECT col FROM count;
まとめると、ユーザ定義の識別子が「予約語と衝突している場合のみ」引用符でくくるというルールは煩雑だと言えます。
#5
総合スコア171
投稿2023/11/28 02:48
他のDBと併用する場合もあるので、バッククォート付けない派です。
特定DBMSに特化した文法も可能な限り避けます。