PLSQL – Improving code efficiency

この質問は、コードとコーディング標準の効率を改善するためのPLSQLに関するものです。

ヘルプ、ポインタ、リファレンス、提案は大歓迎です。

質問:

i_flagタイプがのINPUTパラメータを持つplsqlプロシージャがありますBOOLEAN

このi_flagの値(trueまたはfalseのいずれか)に基づいて、SQLクエリを実行する必要があります。値がTRUESQL1(クエリ1.1と想定)の場合、値がFALSESQL2(クエリ1.2と想定)の場合は実行されます。

SQL2は、where句が追加されていることを除いて、SQL1と同じです。

SQL1(1.1)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id;

SQL1(1.2)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id
and a.user_status is not null;

plsqlでIF-ELSEを記述する代わりに、このクエリを単一のSQLクエリで記述することは可能ですか?sqlオラクル選択するplsqlplsqldeveloperシェアフォローする2015年9月25日18:46に編集ムレイニク246k4545ゴールドバッジ228228個のシルバーバッジ270270個のブロンズバッジ2015年9月25日17:12に 尋ねたディーパン1171ゴールドバッジ1個1シルバーバッジ1個7ブロンズバッジ7個

コメントを追加

5つの答え

アクティブ最古投票3

論理or演算子を使用して、1つのクエリで同じ動作を作成できます。

select a.user_id, a.user_name, a.dept_id, b.country 
from user a , contact b
where a.user_id = b.user_id AND (i_flag = TRUE OR a.user_status IS NOT NULL)

ちなみに、暗黙的な結合(from句に2つのテーブルがある)は非推奨の構文であり、最新の明示的な構文に切り替えることをお勧めします。

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
where  i_flag = TRUE OR a.user_status IS NOT NULL

シェアフォローする2015年9月25日18:46に編集2015年9月25日17:19に 回答ムレイニク246k4545ゴールドバッジ228228個のシルバーバッジ270270個のブロンズバッジ

  • 6booleanは有効なSQLデータ型ではないため、これは機能しません。PL / SQLでのみ有効です。ブールパラメータを、varchar2(1)YまたはNなどのSQL型であるローカル変数に変換する必要があります。その後、そのローカル変数をクエリで使用できます。 – ジャスティン洞窟 2015年9月25日18:49

コメントを追加0

まず、SQLクエリでブールパラメータを使用する場合は、NUMBERなどのSQL互換タイプに置き換える必要があります。つまり、FALSEまたはTRUEの代わりに0または1を使用します。

第2に、ORに基づくMureinikの回答は機能しますが、代替手段を使用すると、Oracleの方がパフォーマンスが向上することがよくあります。1つの選択肢は次のようなものです。

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
WHERE  1 = CASE WHEN i_flag = 1 THEN 1
                WHEN a.user_status IS NOT NULL THEN 1
                ELSE 0 END

それはきれいではありませんが、より大きなクエリでは時々非常に役立ちます。シェアフォローする2015年9月25日22:56に回答ポール・キエニッツ84955つのシルバーバッジ2222個のブロンズバッジコメントを追加0

構文的には、上記の答えはすべて素晴らしいです。しかし、私の2セントは、パフォーマンスに役立つ可能性のある別の変更について言及しています。PL / SQL procを実行する際の最大のボトルネックは、PL / SQLとSQLエンジン(ORACLEのアーキテクチャによって分離されている)の間でバウンスするときに見られます。したがって、経験則では、各プロシージャへの個々の呼び出しの量を最小限に抑えます。

このルールを質問に適用する場合は、クエリ対象のすべてのユーザーとその適切なブール値を含むrefcursorをプロシージャに渡すことが可能かどうかを確認する必要があります。プロシージャがユーザーのバッチのループ内から呼び出されるようになった場合、そうすることで、多数にスケーリングするときにパフォーマンスが大幅に向上します。シェアフォローする2015年9月26日9:47に回答ヤロン・イダン4,80644つのゴールドバッジ3232個のシルバーバッジ6060個のブロンズバッジコメントを追加0

このために動的SQLを作成するのは良い選択だと思います。

create or replace procedure sp_..(i_flag boolean) 
as 
 sql_stmt varchar2(1000):='select a.user_id, a.user_name,'|| 
 'a.dept_id,b.country from user a , contact b '||
 'where a.user_id = b.user_id';
begin 
 if (i_flag=false) then 
   sql_stmt:=sql_stmt||' and a.user_status is not null';
end if;
 ---do some stuff with sql_stmt(i.e. refcursor)
end sp_..;  

シェアフォローする2015年9月26日13:58に 回答ソムナスバンドパディヤイ464ブロンズバッジ4個

  • 1動的SQLのIMOの無用な使用。YMMV。 –  user272735 2015 年9月28日13:13
  • dbms_sql @ user272735を使用しますか? –  Somnath Bandopadhyay 2015 年9月28日13:29
  • @Mureinikが受け入れた回答は(正しい)解決策であるため、これ以上の例を提供する必要はありません。静的SQLで同じ機能を作成できる場合、動的SQLは常に最適ではありません。 –  user272735 2015 年9月30日5:15
  • SQLエンジンはSQL以外の引数を解析しないため、入力パラメーター(i_flag = true)を試してみたことがあると思います。 –  Somnath Bandopadhyay 2015年 10月1日9:52 
  • @Justin Caveはすでに言っています…私はそれを逃しました…静的SQLはそれを行うことができないので、dbms_sqlに依存する必要があります – Somnath Bandopadhyay 2015年 10月1日9:54 

さらに2つのコメントを表示0

単一のクエリ内にor条件を実装できたとしても、パフォーマンスの観点からはあまり良い考えではない可能性があり、動的SQLの方が適している可能性があります。コードの効率を改善したい場合は、https://www.youtube.com/watch?v = rWEqO-GpJ4Mのように見てください。シェアフォローする2015年10月14日13:36に 回答clq1809ブロンズバッジ9個コメントを追加

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA