PL/SQLでデータ変換/処理を行っていますが、パッケージから重複コードを排除したいと考えています。これは関連するコード部分です。
表関数の入力タイプ:
type t_legs_cur is ref cursor return legs%rowtype;
1 つのレコードを処理する手順:
procedure discontinuity_rule(p_leg in out nocopy legs%rowtype) as
begin
null; --business logic here
end discontinuity_rule;
カーソルを反復処理し、カーソル内の各行を処理し、出力 (存在する場合) をパイプ処理する表関数:
function apply_discontinuity_rule(p_cur t_legs_cur)
return t_legs pipelined
order p_cur by (/* some fields */)
parallel_enable (partition p_cur by range (/* some fields */))
as
v_leg legs%rowtype;
begin
loop
fetch p_cur into v_leg;
exit when p_cur%notfound;
discontinuity_rule(v_leg); --call back
if v_leg.id is not null then
pipe row (v_leg);
end if;
end loop;
end apply_discontinuity_rule;
変換/処理にはいくつかのステップがあります。たとえば、次の選択を実行して、いくつかの処理を行い、特定の順序でいくつかのルールを適用します。
select * from table(trip_rules.generate_trips_from_legs(cursor(
select * from table(trip_rules.apply_5_legs_rule(cursor(
select * from table (trip_rules.apply_previous_city_rule(cursor(
select * from table (trip_rules.apply_backhaul_rule(cursor(
select * from table(trip_rules.apply_connection_time_rule(cursor(
select * from table(trip_rules.apply_discontinuity_rule(cursor(
select * from table(trip_rules.generate_legs_from_input(cursor(
select * from INPUT_DATA
)))
)))
)))
)))
)))
)))
)));
これはすべてうまくいきますが、唯一の問題は、私の trip_rule パッケージに多くのapply_*_rule
関数が含まれていることです。それらはすべて例に似ていますapply_discontinuity_rule
。discontinuity_rule
唯一の違いは、コールバックする実際のプロシージャ ( ) です。
だから、私の質問は、どうすればapply_*
関数のコードをコピーするのを避けることができるかということです. これを行うためのよりエレガントな方法はありますか?大きなifを使用します:if p_rule_name == 'discontinuity_rule' then
function apply_rule(p_cur t_legs_cur, p_rule_name in varchar2)
return t_legs pipelined
order p_cur by (/* some fields */)
parallel_enable (partition p_cur by range (/* some fields */))
as
v_leg legs%rowtype;
begin
loop
fetch p_cur into v_leg;
exit when p_cur%notfound;
if p_rule_name == 'discontinuity_rule' then
discontinuity_rule(v_leg);
elsif p_rule_name == 'other_rule' then
other_rule(v_leg);
elsif p_rule_name == 'totally_other_rule' then
totally_other_rule(v_leg);
-- and so on...
end if;
if v_leg.id is not null then
pipe row (v_leg);
end if;
end loop;
end apply_rule;
また、プロシージャ名を使用して匿名の PL/SQL ブロックをオンザフライで作成し、動的 SQL として実行できることも理解しています。自分のパフォーマンスを犠牲にせずに、ちゃんとできるだろうか。どんなアイデアでも大歓迎です。