最近はMySQLのStoredProcedureを書きまくってる生活を送っています。
さて、プログラムの可読性を保つ為に、次のようなテクニックを使うことがあります。
if( 何か条件式 ) { // 何もしないよ! ; } else { // 何か複雑な処理 this.someComplicatedMethod1(); this.someComplicatedMethod2(); this.someComplicatedMethod3(); ... }
「何かの条件式」の評価結果が真であるときに何もしない、というものです。
もちろん、この評価結果の論理否定を用いて
if( !何か条件式 ) { // 何か複雑または長い処理 this.someComplicatedMethod1(); this.someComplicatedMethod2(); this.someComplicatedMethod3(); ... }
という書き方も可能ですし、こちらの方が(ソースコード上は)短いコードになります。
しかしながら、可読性のために、この「何かの条件式」が真のときに何もしないということを意図的に明示したい場面が時々あります。その明示の場所も、複雑な処理の後ではなくて、前にしたいのです。
上記のサンプルはjava(っぽい何か)ですが、言語を問わず、こういう書き方をする方は居られるでしょう。
この表現をするためには、IF文の条件式が真のときの処理内容が何も無くても良い、またはセミコロンだけでも良い、という言語仕様が必要です。
この記事のタイトルにある NOOP とは No Operation の略で「何もしない」という意味です。POP3やSMTP等の通信プロトコールではよくNOOPコマンドが仕様に入っていたりしますね。
MySQLのStoredProcedureでのNOOP操作
MySQLのStoredProcedureでは、次のように、IF文の条件が真のときの処理文は必須なのです。
IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF
(引用元:http://dev.mysql.com/doc/refman/5.6/en/if.html)
構文上、 statement_list は必須ですので、何かしなければなりません。
NOOP操作(java言語で言うところのセミコロンのみの文)は存在しませんので、何かNOOPの代替手段を探してこなければなりません。
まず試したのは、ダミーの変数に値を代入するための SET 文を実行することです。
もちろんこの方法は文法的に上手くいきますが、このためにダミーの変数を設けるのは非常にバカバカしい話です。
可読性を上げるためにNOOP操作をしたいのに、ダミー変数を置くのは本末転倒というところになります。しかも他の言語と違って、変数の定義を処理の先頭でやらなければならないという制約もある訳ですから。
色々調べたところ、NOOP操作としては
select 1;
というダミーのselect文を実行するのが最も優れた方法のようでした。
PostgreSQLの場合
試してはいませんが、PostgreSQLの場合は
NULL;
という書き方もできるようです。詳しくは What to use as a NOOP in PostgreSQL? - Stack Overflow をご覧あれ。
2013年4月14日 追記!
MySQLにおいて
select 1;
このダミーのselect文をStored Procedureに仕込むと文法的には正しくなりますし動作もしますが、
- 実行時にこのselect文の結果が表示(ないしは返却)されてしまう
- 複文(1回のクエリ実行においてセミコロン等を用いて複数のクエリを実行させること)の一部としてプロシージャを起動した場合はエラーになる場合がある(これは他の要因が重なって起こることかもしれない。詳細調査中)
ということがわかりました。
こんなややこしいトラブルには遭遇したくはありませんので、大人しくダミーの変数を宣言して、適当に代入文を仕込むのが良さそうです。