階層構造(木構造)で深さが一定していないデータを辿ったりとか、
条件に合致するまで一定しない数をインクリメントしながら探索するロジックでは
再帰プログラムが有効。
PL/SQLでももちろんできる。
が、末尾最適化みたいなのは調べたけど全くヒットしないので、
再帰回数があまりに多い処理は考え物。
以下に、○週後の週末または月末を返すファンクションを記載
CREATE OR REPLACE FUNCTION BPI_F_GET_WEEKEND(
p$DATE IN DATE,
p$WEEK IN NUMBER,
p$BEGIN_END IN VARCHAR2
)
RETURN DATE
/******************************************************************************/
/* p$DATE 判定する月を入れる。日付も必要だが、月初日でなくてもよい */
/* p$WEEK 何週後かを数値で指定する */
/* p$BEGIN_END 週初め(日曜日)または週末(土曜日)を'B' or 'E'で指定する */
/* 使い方 */
/* SELECT BPI_F_GET_WEEKEND('2010/01/01',1,'B') */
/* ,BPI_F_GET_WEEKEND('2010/01/01',1,'E') */
/* FROM DUAL; */
/******************************************************************************/
IS
p$START_DATE DATE;
p$RET_DATE DATE;
BEGIN
-- 引数の日付を月初日に変換
p$START_DATE := TRUNC(p$DATE, 'MM');
-- 一週目の処理
IF p$WEEK = 1 THEN
IF p$BEGIN_END = 'B' THEN
RETURN p$START_DATE;
ELSIF p$BEGIN_END = 'E' THEN
-- 最初の週の土曜日取得
p$RET_DATE := NEXT_DAY(p$START_DATE - 1, '土');
RETURN p$RET_DATE;
END IF;
ELSE
-- 二週目以降は再帰した返り値にさらに加算
p$RET_DATE := BPI_F_GET_WEEKEND(p$START_DATE, p$WEEK - 1, 'E') + 1;
IF p$BEGIN_END = 'B' THEN
RETURN p$RET_DATE;
ELSIF p$BEGIN_END = 'E' THEN
p$START_DATE := TRUNC(p$RET_DATE, 'MM');
p$RET_DATE := NEXT_DAY(p$RET_DATE - 1, '土');
RETURN LEAST(p$RET_DATE, LAST_DAY(p$START_DATE));
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/
最終更新:2010年09月01日 14:04