読者です 読者をやめる 読者になる 読者になる

職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

MySQL で NOOP 操作

最近はMySQLのStoredProcedureを書きまくってる生活を送っています。

さて、プログラムの可読性を保つ為に、次のようなテクニックを使うことがあります。

if( 何か条件式 ) {
	// 何もしないよ!
	;
}
else {
	// 何か複雑な処理
	this.someComplicatedMethod1();
	this.someComplicatedMethod2();
	this.someComplicatedMethod3();
	...
}

「何かの条件式」の評価結果が真であるときに何もしない、というものです。
もちろん、この評価結果の論理否定を用いて

if( !何か条件式 ) {
	// 何か複雑または長い処理
	this.someComplicatedMethod1();
	this.someComplicatedMethod2();
	this.someComplicatedMethod3();
	...
}

という書き方も可能ですし、こちらの方が(ソースコード上は)短いコードになります。
しかしながら、可読性のために、この「何かの条件式」が真のときに何もしないということを意図的に明示したい場面が時々あります。その明示の場所も、複雑な処理の後ではなくて、前にしたいのです。
上記のサンプルはjava(っぽい何か)ですが、言語を問わず、こういう書き方をする方は居られるでしょう。

この表現をするためには、IF文の条件式が真のときの処理内容が何も無くても良い、またはセミコロンだけでも良い、という言語仕様が必要です。
この記事のタイトルにある NOOP とは No Operation の略で「何もしない」という意味です。POP3SMTP等の通信プロトコールではよく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回のクエリ実行においてセミコロン等を用いて複数のクエリを実行させること)の一部としてプロシージャを起動した場合はエラーになる場合がある(これは他の要因が重なって起こることかもしれない。詳細調査中)

ということがわかりました。
こんなややこしいトラブルには遭遇したくはありませんので、大人しくダミーの変数を宣言して、適当に代入文を仕込むのが良さそうです。