2016-06-22 5 views
0

こんにちは私は条件に基づいて、別の列で選択する必要がある問題があります。私は不完全なIF ELSIF節を持つストアドプロシージャでこれを達成できますが、これを解決する最善の方法を知りたいと思います。ここではそれをより明確にする例を示しますOracle PL/SQL - 条件に基づいて、異なる列でselect、group-by、order-by、where-clauseを実行する最適な方法は?

PROCEDURE notSoSmartSelect(type IN VARCHAR, a_filter IN VARCHAR 
      , b_filter IN VARCHAR, results OUT SYS_REFCURSER) IS 
BEGIN 
    IF type = 'A' THEN 
    OPEN results FOR 
     SELECT a, sum(val) v FROM sample_table 
     GROUP BY a, ORDER BY a; 
    ELSIF type = 'B' THEN 
    OPEN results FOR 
     SELECT b, a, sum(val) v FROM sample_table 
     WHERE a = a_filter 
     GROUP BY b, a, ORDER BY a, b; 
    ELSIF type = 'C' THEN 
    OPEN results FOR 
     SELECT c, b, a, sum(val) v FROM sample_table 
     WHERE a = a_filter AND b = b_filter 
     GROUP BY c, b, a, ORDER BY a, b, c; 
    END IF; 
END; 

あなたが気づいてきたように、それぞれの場合に、使用されるテーブルは同じですが、フィルタ、グループおよび順序を取得するために使用されている別の列があります。

上記のコードはかなり単純に見えますが、実際の問題には多くの分岐があり、複数のif-elseがあり、コードが非常に汚れています。これにアプローチする上品で清潔な方法はありますか?たぶんダイナミックSQL?しかし、私はこのための動的SQLを書くための最良の方法を把握しているようです。前もって感謝します。

答えて

1

私はこれを「汚れた」とは考えていません。クエリはお互いに非常に異なるので、私はそれらを1つのステートメントにマージしようとはしません。

しかし、それらは非常に異なっています(異なる列が選択され、異なる集約グループ、異なるwhere句)、なぜそれらはすべて1つの手順に入っていますか?私はこの3つの手順があればそれを作るだろう。おそらくは3つの意見があります。

0

これは、試したい動的SQLのアプローチよりもはるかに明確です。あなたが言ったように、それは多くのIF ELSEブランチを持っているので、その多くを構築することは非常に退屈になり、多くの条件が"TEST"です。

refcursorは、JAVAのようなフロントエンドアプリケーションで使用されているので、出力全体を戻し、その最後からすべての操作を行う方がよいと思います。

+0

残念ながら、約50万件のレコードがあります。データベースから一度に多くのレコードを取得するには時間がかかりますが、where句を使用したクエリでは約60レコードしか返されません。 – Ocelot

+0

残念ながら、これは私が考えることができる唯一のアプローチです –

関連する問題