2018 03 05

PL/SQLのリファクタリングの2

最初の一歩として、まずは個々の処理毎に分割してみた。

結果はこんな感じ。

create or replace package 月次処理 is PKG_NM constant varchar2(30) := '月次処理' ; -- function 当月分コピー return number ; -- function 納品コピー( p_bgn in date , p_end in date ) return number ; -- function 返品コピー( p_bgn in date , p_end in date ) return number ; -- procedure ログ出力( p_fnc in バッチログ.処理モジュール%type , p_sts in バッチログ.処理状況%type , p_cnt in バッチログ.処理件数%type , p_msg in バッチログ.補足事項%type ) ; end ; / create or replace package body 月次処理 is function 当月分コピー return number is FNC_NM constant varchar2(30) := '当月分コピー' ; FIN_DT constant number := 15 ; v_bgn date ; v_end date ; v_cnt number := 0 ; begin ログ出力( PKG_NM || '.' || FNC_NM , '処理開始' , 0 , null ) ; -- v_bgn := add_months( trunc( sysdate, 'MONTH' ), -1 ) + FIN_DT ; -- 先月16日00:00:00 v_end := add_months( v_bgn, 1 ) - 1 / ( 24 * 60 * 60 ) ; -- 当月15日23:59:59 -- v_cnt := v_cnt + 納品コピー( v_bgn, v_end ) ; v_cnt := v_cnt + 返品コピー( v_bgn, v_end ) ; commit ; -- ログ出力( PKG_NM || '.' || FNC_NM , '正常終了' , v_cnt , null ) ; -- return 0 ; exception when others then rollback ; dbms_output.put_line( dbms_utility.format_error_stack() ); dbms_output.put_line( dbms_utility.format_error_backtrace() ); -- ログ出力( PKG_NM || '.' || FNC_NM , '異常終了' , 0 , sqlerrm ) ; return 1 ; end ; -- function 納品コピー( p_bgn in date , p_end in date ) return number is FNC_NM constant varchar2(30) := '納品コピー' ; v_cnt number := 0 ; begin ログ出力( PKG_NM || '.' || FNC_NM , '処理開始' , 0 , null ) ; -- insert into 月次納品 ( ISBN , 納品先ID , 工場出荷日 , 納品予定日 , 納品実績日 , 価格 ) select ISBN , 納品先ID , 工場出荷日 , 納品予定日 , 納品実績日 , 価格 from 日次納品 where 納品実績日 between p_bgn and p_end ; v_cnt := sql%rowcount ; -- ログ出力( PKG_NM || '.' || FNC_NM , '正常終了' , v_cnt , null ) ; return v_cnt ; exception when others then raise ; end ; -- function 返品コピー( p_bgn in date , p_end in date ) return number is FNC_NM constant varchar2(30) := '返品コピー' ; v_cnt number := 0 ; begin ログ出力( PKG_NM || '.' || FNC_NM , '処理開始' , 0 , null ) ; -- insert into 月次返品 ( ISBN , 納品先ID , 返品予定日 , 返品実績日 , 払戻価格 , 負担割合 , 返品理由 ) select ISBN , 納品先ID , 返品予定日 , 返品実績日 , 払戻価格 , 負担割合 , 返品理由 from 日次返品 where 返品実績日 between p_bgn and p_end ; v_cnt := sql%rowcount ; -- ログ出力( PKG_NM || '.' || FNC_NM , '正常終了' , v_cnt , null ) ; return v_cnt ; exception when others then raise ; end ; -- procedure ログ出力( p_fnc in バッチログ.処理モジュール%type , p_sts in バッチログ.処理状況%type , p_cnt in バッチログ.処理件数%type , p_msg in バッチログ.補足事項%type ) is pragma AUTONOMOUS_TRANSACTION ; PRC_NM constant varchar2(30) := 'ログ出力' ; begin insert into バッチログ ( 日時 , 処理モジュール , 処理状況 , 処理件数 , 補足事項 ) values ( systimestamp , p_fnc , p_sts , p_cnt , p_msg ) ; commit ; exception when others then rollback ; dbms_output.put_line( dbms_utility.format_error_stack() ); dbms_output.put_line( dbms_utility.format_error_backtrace() ); end ; end ; /

機能本体としては以下の3つ。

その他、共通処理としてログ出力。

リファクタリングとは 「振る舞いを変えずにコードを綺麗にすること」 だが、振る舞いは微妙に変えている。 各機能モジュール内でも開始/終了のログを出すようにしたり、ログを独立したトランザクションにしたり。 でも本来の機能については変わらないし、他に適当な言葉もないし、これもリファクタリングでいいだろう。

で、結果を眺めていて気になるのがログ出力の部分。

開始と正常終了と異常終了はパラメーターが違うだけなので共通化してみたのだが、そのために常に使わないパラメーターまで指定しなければいけないことになっている。 逆に、種別に関係なく常に同じ値を設定というか使っているパラメーターもある。 具体的にはパッケージ名。 現状は日時だけを共通モジュール内に隠蔽しているが、パッケージ名もそうしたい。

ということで、明日はログ周りをなんとかしてみる。