最初の一歩として、まずは個々の処理毎に分割してみた。
結果はこんな感じ。
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つ。
その他、共通処理としてログ出力。
リファクタリングとは 「振る舞いを変えずにコードを綺麗にすること」 だが、振る舞いは微妙に変えている。 各機能モジュール内でも開始/終了のログを出すようにしたり、ログを独立したトランザクションにしたり。 でも本来の機能については変わらないし、他に適当な言葉もないし、これもリファクタリングでいいだろう。
で、結果を眺めていて気になるのがログ出力の部分。
開始と正常終了と異常終了はパラメーターが違うだけなので共通化してみたのだが、そのために常に使わないパラメーターまで指定しなければいけないことになっている。 逆に、種別に関係なく常に同じ値を設定というか使っているパラメーターもある。 具体的にはパッケージ名。 現状は日時だけを共通モジュール内に隠蔽しているが、パッケージ名もそうしたい。
ということで、明日はログ周りをなんとかしてみる。