- PR -

oracle10g PL/SQL ストアドプロシージャについて教えてください

1
投稿者投稿内容
satoko
常連さん
会議室デビュー日: 2006/05/06
投稿数: 35
お住まい・勤務地: 東京
投稿日時: 2007-02-09 05:07
いつも勉強させていただいています。
今回は急遽今日までにストアドプロシージャのプログラムを組むことになり、SQL自体が初めてなので助言を頂きたいと思い投稿しました。
こちらで投稿するにはレベルの低い話なのかもしれませんが、質問をする人も居ないのでどなたか助けてください^^;

テーブルT_COSTS
COSTS_DT /* 年月日 */
IN_OUT /* 入出金区分 */
CLASS_CD /* 科目コード */
PRICE /* 金額 */

テーブルT_MNYCHARGE
TRAN_DT /* 繰越日 */
AMOUNT /* 繰越高 */

上記二つのテーブルがあり、
指定された期間(COSTS_DT)内に登録された金額と残高を表示する為のストアドプロシージャを作っています。
例えば、2007/02/01という指定日で表示をしようとすると、
2007/02/01より以前の直近のT_MNYCHARGEの繰越日と繰越高を取得し、
その繰越日から2007/02/28までに登録されているデータの残高を計算しつつ、
表示したい項目と一対一のカラムが存在する一時テーブルにINSERTしたいです。
以下の図は、繰越日が2007/01/31で繰越額が200,000と設定されている時に出したい表示です。

年月日 入出金区分 金額  残高
-------------------------------------
2007/02/01 出金 2000 180000
2007/02/02 出金 1000 170000
2007/02/04 入金 10000 270000
2007/02/07 出金 5000 220000
  ・    ・   ・
  ・    ・   ・
  ・    ・   ・
2007/02/28までに登録されているデータが表示される。

以下はストアドプロシージャのソースの一部です。

FUNCTION SETWORK
(
pLIST_DT IN NUMBER /* 画面から選択された年月 */
)
RETURN NUMBER
IS

sCOSTS_DT NUMBER(8); /* 年月日 */
sLIST_DT NUMBER(8); /* 指定された年月 */
sIN_OUT NUMBER(1); /* 入出金区分 */
sCLASS_CD NUMBER(4); /* 科目コード */
sPRICE NUMBER(13); /* 金額 */
sTRAN_DT NUMBER(8); /* 繰越日 */
sAMOUNT NUMBER(13); /* 繰越高 */
sNEAR_T_DT NUMBER(8); /* 直近の繰越日 */
sNEAR_AMOUNT NUMBER(8); /* 直近の繰越高 */
sLAST_L_DT NUMBER(8); /* 指定された年月の最終日 */
sEXE INTEGER; /* 実行用変数 */
sCUR INTEGER; /* カーソル */
sSTS NUMBER; /* ステータス */
sSQL VARCHAR2(512); /* SQL文編集 */

BEGIN

/* 指定された年月より過去の直近の繰越日を求める */
SELECT MAX(TRAN_DT) INTO sNEAR_T_DT FROM T_MNYCHARGE WHERE TRAN_DT <= sLIST_DT;
/* 直近の繰越日の繰越高を求める */
SELECT AMOUNT INTO sNEAR_AMOUNT FROM T_MNYCHARGE WHERE TRAN_DT = sNEAR_T_DT;
/* 指定された年月の最終日を求める */
sLAST_L_DT := LAST_DAY(TO_DATE(sLIST_DT));
/* SQL設定 */
sSQL := 'SELECT COSTS_DT,IN_OUT,CLASS_CD,PRICE FROM T_COSTS ';
sSQL := sSQL || 'WHERE COSTS_DT BETWEEN ' || sNEAR_T_DT || ' AND ' || sLAST_L_DT || ' ';
/* カーソルオープン */
sCUR := DBMS_SQL.OPEN_CURSOR;
/* SQL文のセット */
DBMS_SQL.PARSE( sCUR, sSQL, DBMS_SQL.V7 );
/* 取得カラム宣言 */
DBMS_SQL.DEFINE_COLUMN( sCUR, 1, sCOSTS_DT );
DBMS_SQL.DEFINE_COLUMN( sCUR, 2, sIN_OUT );
DBMS_SQL.DEFINE_COLUMN( sCUR, 3, sCLASS_CD );
DBMS_SQL.DEFINE_COLUMN( sCUR, 4, sPRICE );
/* カーソル実行 */
sEXE := DBMS_SQL.EXECUTE( sCUR );
/* フェッチ */
sSTS := DBMS_SQL.FETCH_ROWS( sCUR );
WHILE (sSTS <> 0) LOOP
/* フェッチデータ取得 */
DBMS_SQL.COLUMN_VALUE( sCUR, 1, sCOSTS_DT );
DBMS_SQL.COLUMN_VALUE( sCUR, 2, sIN_OUT );
DBMS_SQL.COLUMN_VALUE( sCUR, 3, sCLASS_CD );
DBMS_SQL.COLUMN_VALUE( sCUR, 4, sPRICE );

ここまで作ったのですが、この後の処理の書き方が分かりません。
やりたい事は、
・直近の繰越高(sNEAR_AMOUNT)を元に、それ以降に登録されているsCLASS_CDの金額を、入出金区分(IN_OUT)によって±しながら残高を求める。
・sCOSTS_DTが、指定された年月(sLIST_DT)に入ったら一時テーブルにINSERTしたい。
・sCOSTS_DTが、指定された年月の最終日(sLAST_L_DT)を過ぎたらLOOPを抜けて処理を終了したい。
です。

説明が下手で分かりづらいかと思いますが、
どうか助言をよろしくお願いします。

[ メッセージ編集済み 編集者: satoko 編集日時 2007-02-09 05:08 ]
未記入
大ベテラン
会議室デビュー日: 2006/12/15
投稿数: 157
投稿日時: 2007-02-09 15:02
前置き長すぎ。
聞きたいことは
1、WHILEの終了方法
2、WHILE中の他テーブル(一時テーブル)へのINSERT方法
ってこと?

SAK StreetsさんのSQLの説明ページ見れば大体片付くかと。
http://homepage2.nifty.com/sak/
1

スキルアップ/キャリアアップ(JOB@IT)