質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

検索フォームで複数条件が指定された場合のSQLを動的にしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 125

mipdq

score 1

前提・実現したいこと

初心者PGです。
検索フォームを開発しています。
画面に3つのボタン(SQLでのちのWHERE句の条件になります)があり、
その押下状況(値)によってDBをSELECTし、結果を表示したいです。
DBはSQLServer、言語はJava(Seasar2)です。

・ボタンは「いぬ(value:AA)」「ねこ(value:BB)」「それ以外(value:CC)」の3つです。
・検索しにいくカラム名はanimalCDです。
・ボタンは複数選択可能です。
・この項目は必須項目です。

「いぬ」が選択された場合に発行したいSQL(実際にこの通りに発行したいわけではなく結果をこのSQLで得られる結果にしたいです)

select * from ANIMALTABLE where animalCD = 'AA'


「ねこ」が選択された場合に発行したいSQL

select * from ANIMALTABLE where animalCD = 'BB'


「それ以外」が選択された場合に発行したいSQL

select * from ANIMALTABLE where animalCD NOT IN ('AA','BB')

「それ以外」はvalueを持っていますが、DBのanimalCDには"CC"という値は存在しません。
「いぬ」「ねこ」の2つが選択された場合も両方に該当する結果を表示します。
「いぬ」「ねこ」「それ以外」の3つが選択された場合も然りです。

どのボタンが押されてどの組み合わせにも対応できるよう、SQLを動的にしたいです。

試したこと

該当のSQLファイルを以下のようにしました。
変数animalCdには画面から取得したanimalCdをリストで保持しSQLファイルに渡します。

select * from ANIMALTABLE
where
/*IF animalCd != null*/       -- 必須項目のためnullの場合は考慮しない
animalCD IN /*animalCd*/('AA','BB')
/*END*/
/*IF animalCd == "CC"*/       -- 「それ以外」が選択されている場合
OR animalCD NOT IN ('AA','BB')
/*END*/

起こっていること、聞きたいこと

animalCdをリストで保持しているからなのか、
/*IF animalCd == "CC"*/ /*END*/
のコメント部の条件判定がいつもfalseになり機能しません。
また、この質問を書いていて気が付いたのですが私がやりたいこととしては
条件を「animalCdに"CC"(それ以外)が含まれていた場合」としたいのです。
要は発行されるSQLとしては、「いぬ」「それ以外」が選択された場合

select * from ANIMALTABLE
where
animalCD IN ('AA')
OR
animalCD NOT IN ('AA','BB')


…とされることを想定していました。

SQLファイル内でそんな条件を書くことは可能なのでしょうか。
可能でなければほかにどのようなやり方があるでしょうか。
また、SQLの組み立て方、仕様としてどうなのか?等々ありましたら
是非教えていただければ幸いです。

拙い文章でわかりにくく申し訳ありませんが、よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Orlofsky

    2020/02/14 18:51

    質問にテーブル定義のCREATE TABLEとテーブル中のデータはINSERTで https://teratail.com/help/question-tips#questionTips3-7 の [コード] で追記されては?

    キャンセル

  • CHERRY

    2020/02/14 19:57

    > Seasar2でのSQLファイルの操作は、/*IF 条件*/ /*END*/で囲い、
    条件がtrueならその中の処理を行うような仕様だったと思います。

    SQL は、どのように実行させるのでしょうか?
    ツールやミドルウェアを使っているのであれば、記載してください。

    キャンセル

  • mipdq

    2020/02/14 20:21

    コメントありがとうございます。

    私も数日前に初めて見たシステムのためよく理解できていないのですが、おそらく、
    >検索、更新処理等を行うSQL文を記述します。 Daoに定義したメソッドを呼び出すと、対応するSQLファイルに記述されているSQL文が発行されます。 作成したSQLファイルはDaoと同じ場所に配置してください。 ※S2DaoにはSQLを自動で生成する機能が用意されているので、SQLファイルがない場合、S2DaoがSQL文を自動生成します。
    これだと思います。
    以下引用元です。
    http://s2dao.seasar.org/ja/s2dao.html#SqlAnnotation

    キャンセル

回答 3

check解決した方法

0

みなさま、コメントいただきありがとうございました。

リストの展開のされ方が調べてもどうしてもわからなかったため、
今回は java のほうでリスト内を検索し、「その他」があった場合フラグを立てて
そのフラグも SQL に渡すことで SQL を条件分岐させることにしました。

Seasar2 の情報が少ない中、わざわざ調べていただいたりコメントいただき感謝しております。
とても勉強になりました。
ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

@prm に入力値があるとすると

declare @prm nvarchar(20) = 'CC';

select * from ANIMALTABLE
where
animalCD = @prm
or (@prm = 'CC' and animalCD not in ('AA', 'BB'))

Seasar2 は知らないのでテストしてほしいのですが、
検索すると http://s2container.seasar.org/2.4/ja/s2jdbc_manager_sqlfile.html
/*prm*/という形式で置き換えられるらしいので次のようになるのではないでしょうか?

select * from ANIMALTABLE
where
animalCD = /*prm*/''
or (/*prm/*'' = 'CC' and animalCD not in ('AA', 'BB'))

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/18 18:08

    なるほど…!
    現状、java のほうで画面のパラメタがリスト化されて SQL ファイルに記述された SQL が発行されるため、
    SQL を発行する直前でリストを分解する処理を加えてみたいと思います。
    何度もお聞きして申し訳ないのですが、
    (@inu = 1 AND animalCD = 'AA') の 1 は何を指しているのでしょうか…

    キャンセル

  • 2020/02/18 18:11

    SQLで書いた時です。Seasar2 で
    (/*inu*/0 = 1 AND ...(略
    とかになるのではないでしょうか。

    キャンセル

  • 2020/02/18 18:31

    とりあえず 1 を代入して null になって落ちるのを防ぐ、ということでしょうか…?

    キャンセル

-1

select * from ANIMALTABLE
where
/*IF animalCd != null*/       -- 必須項目のためnullの場合は考慮しない
animalCD IN /*animalCd*/('AA','BB')
/*END*/
/*IF animalCd == "CC"*/       -- 「それ以外」が選択されている場合
AND animalCD NOT IN ('AA','BB')
/*END*/

  ↓  コメントがううざいので削ってちょっと整形

select * from ANIMALTABLE
where
    animalCD     IN ('AA','BB')  -- 'AA か 'BB' のデータを対象とする
AND animalCD NOT IN ('AA','BB')  -- 'AA でも 'BB' でもないデータを対象とする2つの条件の AND (両方を満たす)という意味ですから、
そんなデータは存在しないので 0 件のデータが対象になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/14 19:59

    アドバイスありがとうございます。
    Seasar2を使用した既存システムの改修のため、フレームワークから変更することは現状とても難しいのです…。
    EOLしていますし私もどうなのかなと思ってはいるのですが…

    キャンセル

  • 2020/02/18 00:47

    >/*IF animalCd == "CC"*/ -- 「それ以外」が選択されている場合


    >OR animalCD NOT IN ('AA','BB')
    は意味が違います。

    ソフトウェアが使われなくなるのは、もっと良い競争相手ができたり、大きな回避できないバグが直らないなどが考えられます。

    Seasar2 のバグも疑った方が良いかも?

    キャンセル

  • 2020/02/18 15:34

    コメントありがとうございます。

    意味が異なるのは承知しているのですが、
    検索先のanimalCDには"CC"という値は存在しないため、
    「その他」が選択された場合は「いぬ」「ねこ」以外のデータを表示したい、という意味合いでした。
    わかりにくく申し訳ありません。

    バグも疑ったほうが良いのですね…勉強になります。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる