2012-10-19 11 views
2

PL/SQL에서 데이터 변환/처리를하고 있는데 은 내 패키지에서 중복 코드을 제거하고 싶습니다. 이것은 관련 코드 부분입니다. 테이블 함수오라클 PL/SQL의 콜백 함수

입력 유형 : 하나 개의 기록 처리

type t_legs_cur is ref cursor return legs%rowtype; 

절차 :

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_* 함수의 코드를 복사하지 않도록 할 수 있습니다. 이 작업을 수행하는 더 우아한 방법은 사용이되는 경우 큰 : 나는 또한 프로 시저 이름을 사용하여 즉석에서 익명 PL/SQL 블록을 생성하고로 실행할 수있을 것이라고 이해 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; 

동적 SQL. 내 성능을 죽이지 않고 제대로 할 수 있는지 궁금해. 어떤 생각이라도 감사합니다.

답변

3

거대한 IF 문은 중복 코드가 아닙니다.

사실, 그것은 ...

elsif p_rule_name == 'totally_other_rule' then 
    totally_other_rule(v_leg); 

동적 PL/SQL을

elsif p_rule_name == 'other_rule' then 
    other_rule(v_leg); 

가 ... 가장 확실히이 동일하지 않습니다 서로하지만,이 닮은 부분을 가지고 있습니다 ... 정말로 대안이 없다면 우리가해야 할 일입니다. 여기에는 그럴 필요가 없습니다.

+0

답장을 보내 주셔서 감사합니다. 당신 말이 맞습니다. 큰 질문이라면,이 질문을 게시하기 전에'apply _ * _ rule' 함수를 복제하는 것이 나쁘지는 않습니다. 나는이 질문을 표현하면서 큰 것을 생각해 냈다. 그리고 더 나은 선택이 없다면 나는 그것을 갈 것입니다. – bpgergo