はじめに
SQL文の条件指定で”where 1 = 1″を指定した場合、この条件は必ず真になり、全てのカラムが条件を満たすようになります。
これはSQLインジェクションで用いられることで有名ですが、プログラムでSQL文を生成する時(動的SQLを用いる時)に”where 1 = 1″を利用すると便利なことがあります。
この記事では、以下のユーザーマスタテーブルを例に挙げて説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-- テーブル定義 create table user_master ( user_id CHAR(4) NOT NULL, user_name VARCHAR(10) NOT NULL, password VARCHAR(10) NOT NULL, PRIMARY KEY (user_id) ); -- データをセット insert into user_master values("0001","hoge","password"); insert into user_master values("0002","fuga","password"); insert into user_master values("0003","piyo","piyopiyo"); |
“where 1 = 1″の使用例
例1:全件抽出
全件抽出したい場合、以下のSQL文1やSQL文2のように書くことができます。
プログラムでSQL文を生成・発行する場合、条件が何も指定されていなければwhere句を外す必要があります。
しかし、条件として”1 = 1″を指定すると、このwhere句の要否の判断をすることなく全件抽出が可能になります。
【SQL文1】
1 2 |
select * from user_master order by user_id; |
【SQL文2】
1 2 3 |
select * from user_master where 1 = 1 order by user_id; |
【結果】
1 2 3 4 5 6 7 8 |
+---------+-----------+----------+ | user_id | user_name | password | +---------+-----------+----------+ | 0001 | hoge | password | | 0002 | fuga | password | | 0003 | piyo | piyopiyo | +---------+-----------+----------+ 3 rows in set (0.00 sec) |
例2:条件指定
“0001”を除くユーザーIDについて、パスワードの文字列に”password”を設定したユーザーを探す要件があるとします。
この場合も、以下のように2通りに書き方があります。
プログラムでSQL文を生成する場合、SQL文1よりもSQL文2の方が楽に生成できます。
条件を追加する際、SQL文1では、最初の条件であるか否かで”where”をつけるか”and”をつけるか判断する必要がありますが、SQL文2では”where 1 = 1″の箇所が固定であるため、この判断が不要(必ず”and”をつければ良い)となります。
【SQL文1】
1 2 3 4 |
select * from user_master where user_id <> "0001" and password = "password" order by user_id; |
【SQL文2】
1 2 3 4 5 |
select * from user_master where 1 = 1 and user_id <> "0001" and password = "password" order by user_id; |
【結果】
1 2 3 4 5 6 |
+---------+-----------+----------+ | user_id | user_name | password | +---------+-----------+----------+ | 0002 | fuga | password | +---------+-----------+----------+ 1 row in set (0.00 sec) |
SQL文の生成ロジック
2つの例で述べたSQL文1とSQL文2について、それぞれの生成ロジックは以下の通りです。
このように、”where 1 = 1″を使うSQL文2の方が、生成ロジックをシンプルにできることがわかります。
【SQL文1生成ロジック(”where 1 = 1″を使わない場合)】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
SQL文の文字列に"select * from user_master "を記述。 if (ユーザーIDの除外条件が指定されている) { if (最初の条件指定) { SQL文の文字列に"where "を追記。 } else { SQL文の文字列に"and "を追記。 } SQL文の文字列に"user_id <> 指定されたユーザーID"を追記。 } if (パスワードが指定されている) { if (最初の条件指定) { SQL文の文字列に"where "を追記。 } else { SQL文の文字列に"and "を追記。 } SQL文の文字列に"password = 指定されたパスワード"を追記。 } |
【SQL文2生成ロジック(”where 1 = 1″を使う場合)】
1 2 3 4 5 6 7 |
SQL文の文字列に"select * from user_master where 1 = 1 "を記述。 if (ユーザーIDの除外条件が指定されている) { SQL文の文字列に"and user_id <> 指定されたユーザーID"を追記。 } if (パスワードが指定されている) { SQL文の文字列に"and password = 指定されたパスワード"を追記。 } |
あとがき
今回は、前回の記事の続きとして、動的SQLで便利なテクニックを紹介しました。
「動的SQLってそもそも何?」と思った方は、前回の記事も是非ご覧ください。
株式会社サイゼントでは、即戦力のJavaプログラマーを育てるための書籍「絶対にJavaプログラマーになりたい人へ」をKindleで販売しています。
同じく、Spring Frameworkについてきめ細かく解説した別冊も販売中です。
また、上記の書籍をテキストとして用いたプログラミングスクール「サイゼントアカデミー」も開校しています。
このスクールは、受託開発事業・SES事業である弊社が、新入社員向けの研修で培ったノウハウを詰め込んだものです。
ご興味がある方は、上記画像から個別ページにアクセスしてみてください!
コメント