2012-03-28 14 views
0

可能かどうかわかりませんが、問合せのフェッチ中に別のプロシージャのデータを参照するプロシージャを作成する必要があります。カーソルのフェッチのプロシージャの呼び出し

例:以下は

は私の構造がどのように本物の別の例である:

TYPE T_CURSOR IS REF CURSOR; 

PROCEDURE PR_ACCOUNT_ACTIVE(CCURSOR OUT T_CURSOR) IS 

    CURSOR CURSOR_ACCOUNT IS 
     SELECT ID_ACCOUNT, NAME, 0 AS SUM_BALANCE 
      FROM ACCOUNT 
     WHERE STATUS = 'A' 
     ORDER BY DATE_CREATE DESC; 

    REG_ACCOUNT CURSOR_ACCOUNT%ROWTYPE; 

    BEGIN 

     OPEN CURSOR_ACCOUNT; 
     LOOP 

      FETCH CURSOR_ACCOUNT INTO REG_ACCOUNT; 
      EXIT WHEN CURSOR_ACCOUNT%NOTFOUND; 

      /*** 
      At this point I need to call the procedure PR_ACCOUNT_BALANCE (below) and 
      her return and use (field SUM_VAL_MONEY) to update the field SUM_BALANCE 
      this current cursor (CURSOR_ACCOUNT) and then return to the cursor CCURSOR 
      ***/ 

     END LOOP; 
     CLOSE CURSOR_ACCOUNT; 

    END; 

END PR_ACCOUNT_ACTIVE; 


PROCEDURE PR_ACCOUNT_BALANCE(P_ID_ACCOUNT IS NUMBER, CCURSOR OUT T_CURSOR) IS 

    BEGIN 

    OPEN CCURSOR FOR 

     SELECT ID_ACCOUNT 
     , SUM(VAL_MONEY) AS SUM_VAL_MONEY 
     FROM ACCOUNT_CONTRIBUTION 
     WHERE ID_ACCOUNT = P_ID_ACCOUNT 
     GROUP BY ID_ACCOUNT 

END PR_ACCOUNT_BALANCE; 

私の大きな問題は、両方の手順で、リターンは常にカーソルによって行われていることである、と私はできませんそれを変えなさい。

これを解決する方法はありますか?

+1

を更新しながら、私は私はあなたが解決しようとしている問題を理解していることはよく分からないカーソルとwhere current ofupdate clauseを使用することができます。 「別の手順でデータを参照する」とはどういう意味ですか? 'PROC_1'には' FETCH'がありますが、あなたは何にもフェッチしていません。 'FETCH'の後の' c1'はカーソルではなくレコードであるはずですか? 'c1'レコードの' field1'に何を割り当てたいのですか? –

+0

@rafael:まず、 'proc_2'を入力するために' proc_1'の 'c1.field1'''最初のカーソル'から 'fetch'を使い、次に' proc_2'から 'cursor'を返しますか? 'proc_1'の中で何らかの操作をしますか?はいの場合はこれが可能です。 –

+0

@ GauravSoni私はより良い理解を得るために私の質問の例を変更しました。しかし、彼の主張は正しい、それは私がやるべきことだ。 –

答えて

0
PROCEDURE PR_ACCOUNT_ACTIVE(CCURSOR OUT T_CURSOR) IS 

CURSOR CURSOR_ACCOUNT IS 
    SELECT ID_ACCOUNT, NAME, 0 AS SUM_BALANCE 
     FROM ACCOUNT 
    WHERE STATUS = 'A' 
    ORDER BY DATE_CREATE DESC; 

REG_ACCOUNT CURSOR_ACCOUNT%ROWTYPE; 

--create a record to fetch the value of the cursor 
TYPE p_rec is RECORD 
(
    ID_ACCOUNT ACCOUNT.ID_ACCOUNT%TYPE 
,SUM_VAL PLS_INTEGER 
); 

v_rec p_rec; --variable of that record 

BEGIN 

    OPEN CURSOR_ACCOUNT; 
    LOOP 

     FETCH CURSOR_ACCOUNT INTO REG_ACCOUNT; 
     EXIT WHEN CURSOR_ACCOUNT%NOTFOUND; 
      PR_ACCOUNT_BALANCE(REG_ACCOUNT.ID_ACCOUNT,v_cursor); 
      FETCH v_cursor INTO v_rec; 
       UPDATE ACCOUNT SET sum_balance=v_rec.sum_val 
        WHERE id_account=v_rec.id_account --assuming id_account is primary key of accounts table 
      CLOSE v_cursor; 

    END LOOP; 
    CLOSE CURSOR_ACCOUNT; 

END; 

END PR_ACCOUNT_ACTIVE; 

PROCEDURE PR_ACCOUNT_BALANCE(P_ID_ACCOUNT IS NUMBER, CCURSOR OUT T_CURSOR) IS 

BEGIN 

    OPEN CCURSOR FOR 

    SELECT ID_ACCOUNT 
    , SUM(VAL_MONEY) AS SUM_VAL_MONEY 
    FROM ACCOUNT_CONTRIBUTION 
    WHERE ID_ACCOUNT = P_ID_ACCOUNT 
    GROUP BY ID_ACCOUNT 

END PR_ACCOUNT_BALANCE; 

私は、コードをコンパイルしていないが、私は、これはあなたのアプローチのアイデアを与えるだろうと思います。

提案

  1. あなたはOracle11gを使用している場合、このプロシージャ・コールを最適化するために、automatic subprogramming inline機能を使用します。 link
+0

@RafaeldePaula:このコードを試してください。問題が発生した場合は、エラーログを教えてください.thanks –

+0

ありがとうございます!私はこのコードを使って、それがうまくいくかどうかを言うつもりです。 –

+0

Gaurav、あなたが行ったように上記の構造を使用して、それは完全に働いた。しかし、私がしたいのは、ACCOUNTの更新ではなく、フィールドSUM_BALANCE CURSOR_ACCOUNTの戻り値を代入し、最初のプロシージャ(出力カーソル)をCCURSORに戻します。これを行う必要がありますか、または一時的なテーブルで作業する必要がありますか? –

関連する問題