DBFluteでの外だしSQLのちょっとしたテクニック2
というわけでDBFluteを使っている時のちょっとしたテクニックパート2です。
検索条件によって参照するテーブルを変更したい場合、
例えば検索画面とかである項目にチェックや条件が入力されていたら
参照するテーブルを変更したいといった時です。
どういう事かというと、
SELECT h.a, h,b, hh.aa, hh.bb FROM hoge h, hogehoge.hh WHERE 1 = 1 /*IF pmb.fuga != null*/AND h.fuga = /*pmb.fuga*/''/*END*/ /*IF pmb.fugafuga != null*/AND h.fugafuga = /*pmb.fugafuga*/''/*END*/ /*IF pmb.ora != null*/AND hh.ora = /*pmb.ora*/''/*END*/ /*IF pmb.oraora != null*/AND hh.oraora = /*pmb.oraora*/''/*END*/
とあった場合、
ある検索条件であればhogehogeテーブルしか検索させたく無いとします。
(WHERE句の中の1=1は昨日のブログを見てね)
そういう場合、
SELECT /*IF pmb.xxxx = null*/h.a ,h.b -- ELSE hh.aa ,hh.bb /*END*/ FROM /*IF pmb.xxxx = null*/hoge h -- ELSE hogehoge hh /*END*/ WHERE 1 = 1 /*IF pmb.xxxx = null*/ /*IF pmb.fuga != null*/AND h.fuga = /*pmb.fuga*/''/*END*/ /*IF pmb.fugafuga != null*/AND h.fugafuga = /*pmb.fugafuga*/''/*END*/ -- ELSE /*IF pmb.ora != null*/AND hh.ora = /*pmb.ora*/''/*END*/ /*IF pmb.oraora != null*/AND hh.oraora = /*pmb.oraora*/''/*END*/ /*END*/
と書きたいところですが、sql2entityバッチを実行させるとエラーが発生します。
理由はhogehogeテーブルであるhhなんてエイリアスありませんぜ旦那という事で怒られてしまいますorz
アプリ上からなら実行させればこのSQLでもDBFluteがパースして問題なく実行してくれるのですが、
sql2entityバッチが使えないとなると問題です。
回避方法としては
FROM /*IF pmb.xxxx = null*/hoge h -- ELSE hogehoge hh /*END*/
の部分を
FROM /*IF pmb.xxxx = null*/hoge h -- ELSE ,hogehoge hh /*END*/
とすれば良いのですがこれだとpmb.xxxxがnull以外だと不要な「,」が入っているためSQL実行エラーとなってしまいますorz
これは困ったんと言う訳で考えた結果、
非常に不格好ですが、以下の通りとなりますた。
SELECT /*IF pmb.xxxx = null*/h.a ,h.b -- ELSE hh.aa ,hh.bb /*END*/ FROM /*IF pmb.xxxx = null*/hoge h -- ELSE (SELECT 'A' FROM DUAL) A ,hogehoge hh /*END*/ WHERE 1 = 1 /*IF pmb.xxxx = null*/ /*IF pmb.fuga != null*/AND h.fuga = /*pmb.fuga*/''/*END*/ /*IF pmb.fugafuga != null*/AND h.fugafuga = /*pmb.fugafuga*/''/*END*/ -- ELSE /*IF pmb.ora != null*/AND hh.ora = /*pmb.ora*/''/*END*/ /*IF pmb.oraora != null*/AND hh.oraora = /*pmb.oraora*/''/*END*/ /*END*/
要は太字のイタリックの箇所である
(SELECT 'A' FROM DUAL) A
を追加しました。
こうする事でsql2entityバッチもアプリからも問題なく実行されます。
実行結果はこんな感じ。
SELECT hh.aa ,hh.bb FROM (SELECT 'A' FROM DUAL) A ,hogehoge hh WHERE 1 = 1 AND hh.ora = 'ora' AND hh.oraora = 'oraora'
となり無事にSQLは実行されます。
ようはWHERE句にある1 = 1と同じで、
無理矢理「,」を付けたいが為に
(SELECT 'A' FROM DUAL) A
を記述しているわけです。
DUALテーブルを使っているからパフォーマンスも特に影響はないですしね。
こんな事するぐらいならSQL分ければ良いじゃんと言われそうですが、
機能をまとめたかったので仕方なくこうしてます。
ていうか他に方法があるなら誰が教えてくだしあ(><)