2016-10-28 72 views
0

Oracleカーソルでデータを戻すプロシージャをoracleデータベースに作成しました。このカーソルの行数を出力変数として戻したいとします。テストの後、P_count変数は正しく入力されますが、カーソルを開こうとすると 'ORA-01002:フェッチ・アウト・オブ・シーケンス'エラーが発生します。私はそれについて前に読んで、私は私のコードでフェッチステートメントを使用しているため、問題があることがわかりました。しかし、今まで私はそれを解決する方法を発見しませんでした。どんな助けでも感謝します、ありがとう。以下は私の手順です:ORA-01002:順序がフェッチされていません

PROCEDURE IS_CLIENT_LOGGED_IN (
    P_CLIENT_NUM Varchar2, 
    P_CURSOR out SYS_REFCURSOR , 
    P_COUNT OUT NUMBER, 
    P_ERROR out Varchar2 
) AS 
    cur_rec Varchar2(1024); 
BEGIN 
    BEGIN 
    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    LOOP 
     FETCH P_CURSOR INTO cur_rec; 
     EXIT WHEN P_CURSOR%notfound; 
     P_COUNT := P_CURSOR%rowcount;--will return row number beginning with 1 
    END LOOP; 
    EXCEPTION WHEN OTHERS THEN 
    P_ERROR := 'Unable to select Data from tbl_registration' ||SQLERRM; 
    END;  
END IS_CLIENT_LOGGED_IN; 
+1

カーソルを使用した後、カーソルを閉じる必要があります。 –

+1

プロシージャの目的は何ですか?通常、 'SYS_REFCURSOR'を返すと、呼び出しブロックによってレコードがフェッチされます。行がすでにフェッチされている場所でカーソルを戻すべきではありません。 –

+0

このプロシージャは別のプロシージャで実装されています。したがって、他のプロシージャでループするためのカウンタを戻すための行カウントと、他のプロシージャでも取り出されたデータを処理するカーソルが必要です。 LOOPの前にCLOSE P_CURSORを追加すると、ループ中にカーソルを定義できませんでしたが、END LOOPの後に追加したときにORA-24338文のハンドルが実行されませんでした。ありがとうございます@WernfriedDomscheit –

答えて

0

あなたのコメントに基づいて、手順は次のようにする必要があります:

PROCEDURE IS_CLIENT_LOGGED_IN (
    P_CLIENT_NUM Varchar2, 
    P_CURSOR out SYS_REFCURSOR , 
    P_COUNT OUT NUMBER, 
    P_ERROR out Varchar2 
) AS 
    cur_rec Varchar2(1024); 
BEGIN 
    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    LOOP 
     FETCH P_CURSOR INTO cur_rec; 
     EXIT WHEN P_CURSOR%notfound; 
     P_COUNT := P_CURSOR%rowcount;--will return row number beginning with 1 
    END LOOP; 
    CLOSE P_CURSOR; 

    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    EXCEPTION WHEN OTHERS THEN 
    P_ERROR := 'Unable to select Data from tbl_registration' ||SQLERRM; 
END IS_CLIENT_LOGGED_IN; 

あまり効率的で、それはあなたが尋ねたものです。 とにかく、P_COUNTを1つずつ増やす理由はありません。

同じを取得するために

SELECT COUNT(*) INTO P_COUNT 
    FROM tbl_registration 
    WHERE tbl_client_id = P_CLIENT_NUM 
     AND tbl_logout_date is null; 

Open P_CURSOR FOR 
    SELECT ID 
    FROM tbl_registration 
    WHERE tbl_client_id = P_CLIENT_NUM 
     AND tbl_logout_date is null; 

してください。

+0

実際には、私は2つの選択を避け、カーソルの行を数えて1つの選択から結果を得るようにしようとしました、とにかく@Wernfried Domscheit –

関連する問題