4

Delphi 7、Oracle 10、および ODAC コンポーネントを使用しています。

LoadTrainResult メソッドから、storedProc を呼び出しています。

    procedure TfrmTrain.LoadTrainResult;  
    begin  
        StoredProc.StoredProcName :=  'PTRAIN.QTRAIN';    
        StoredProc.Prepare;  
    try        
        StoredProc.ParamByName('P_COURSE').AsString  := CurrentSearch.Course;  
        StoredProc.ParamByName('P_TOPIC').AsString   := CurrentSearch.Topic;  
        StoredProc.ParamByName('P_EMP').AsString     := CurrentSearch.Emp;  
        StoredProc.Open;  
    finally  
        StoredProc.Close;  
    end;  
    end; 

スキーマは

    Create or replace PACKAGE TRAIN.pTRAIN  IS 
    TYPE CursorType IS REF CURSOR;   
    PROCEDURE QTRAIN   (p_CursorVar OUT CursorType, p_Course in VarChar2, 
                            p_Topic  in out VarChar2, p_emp in Varchar 2 );  
    END TRAIN.pTRAIN;

    create or replace PACKAGE BODY  TRAIN.pTRAIN  IS  
    PROCEDURE QTRAIN   (p_CursorVar OUT CursorType, p_Course in VarChar2, 
                            p_Topic in out  VarChar2, p_emp in Varchar 2 ) 

    IS    
    BEGIN   
            if p_course is not null then  
            OPEN p_cursorvar for    
                    select * from train.course 
                    where course = p_Course;  
            elsif p_topic is not null then  
            OPEN p_cursorvar for  
                    select * 
                    from train.topic
                    where topic = p_topic;
    end if;         
    Exception
            WHEN OTHERS THEN
            p_TOPIC := '';  
    END QTRAIN;  
    END TRAIN.pTRAIN;

パッケージをコンパイルしているとき、エラーは発生しませんでした。ただし、アプリケーションを実行しているときにエラー ORA-24338: ステートメント ハンドルが実行されていません。アプリケーションをデバッグしたところ、StoredProc.Prepare でエラーが発生したことがわかりました。StoredProc.ExecProc ではありません。

ORA-24338 に関する非常に多くの投稿を読みましたが、自分のコードの何が問題なのかを見つけることができませんでした。

私がストアドプロシージャにelse条件を追加すると、エラーが発生しないことがわかりました。

変更されたProcは

    create or replace PACKAGE BODY  TRAIN.pTRAIN  IS  
    PROCEDURE QTRAIN   (p_CursorVar OUT CursorType, p_Course in VarChar2,
                             p_Topic in out  VarChar2, p_emp in Varchar 2 )  
    IS    
    BEGIN   
            if p_course is not null then  
            OPEN p_cursorvar for    
            select *    from train.course 
       where course = p_Course; 

            elsif p_topic is not null then
            OPEN p_cursorvar for
            select * from train.topic
       where topic = p_topic  

            else   
            OPEN p_cursorvar for  
            select * from emp whhere empid = p_emp; 

            end if;
            Exception
            WHEN OTHERS THEN
            p_TOPIC := '';  
            END QTRAIN;  
    END TRAIN.pTRAIN;

実際、私は他の条件を望んでいません。エラーを取り除く方法はありますか。

4

3 に答える 3

6

問題は、ストアド プロシージャの最初のバージョンでは返される結果セットがない可能性がありますが、2 番目のバージョンでは、最後の else で結果セットを提供したことです。

完全なエラー レポートを見て ORA-24338 の意味を理解すると、私の疑念はさらに強くなります。

Error: ORA-24338
Text: statement handle not executed 
---------------------------------------------------------------------------
Cause: A fetch was attempted before executing a statement handle. 
Action: Execute a statement and then fetch the data.

フェッチが試行されましたが、場合によっては、最後の else を指定するまで、フェッチする結果セットがありませんでした。

ストアド プロシージャは出力パラメーターによってカーソルを返すため、常にそのカーソルを開く必要があります。コードの最初のバージョンでは、そうではありませんでした。

于 2013-09-19T14:33:17.003 に答える
0

DevArt は 2007 年 8 月 2 日に、「REF カーソル パラメータが修正された準備済みストアド プロシージャの実行に関するバグ」というバグ修正を行いました。バグ修正リストのその声明で提供されたもの以外に、追加の詳細はありません。お使いのバージョンの ODAC にそのバグが含まれている可能性があります。ODAC は現在、バージョン 8.2.8 です。

于 2012-08-17T18:57:12.700 に答える
0

DB パッケージ自体に問題は見られませんPTRAINが (スキーマはTRAIN)、呼び出し元のアプリケーション (Delphi 7?) はcursor. また、次のようにカーソルを開いているときに動的SQLを使用してみてください-

OPEN p_cursorvar for    
'select * from train.course 
where course = :p_Course' USING p_course;

OPEN p_cursorvar for  
'select * 
from train.topic
where topic = :p_topic' USING p_topic;
于 2012-08-16T22:13:07.633 に答える