ORA-24338:语句句柄未执行

问题描述 投票:0回答: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 条件时我没有收到错误。

修改后的过程是

    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;

其实我不想要别的条件。有什么办法可以消除这个错误吗?

oracle delphi delphi-7 odac
4个回答
7
投票

在我看来,问题是:在存储过程的第一个版本中,可能没有结果集可返回,但在第二个版本中,您在最后一个版本中提供了结果集。

当我们通过查看完整的错误报告了解 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。

您的存储过程通过输出参数返回游标,因此您“总是”必须打开该游标。在你的代码的第一个版本中,你没有。


0
投票
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;



0
投票


0
投票

Exception WHEN OTHERS THEN p_TOPIC := ''; END QTRAIN;

当其他人告诉 Oracle 放弃所有错误消息时。您的存储过程可能会遇到其他错误,并且您不知道发生了什么。 ORA-24338 可能是因为发生了另一个错误并且游标从未打开。

如果您不使用 WHEN OTHERS,Oracle PL/SQL 具有强大的错误处理能力。 Oracle 自动回滚事务并提供完整的错误堆栈,包括导致错误的语句的行号。

© www.soinside.com 2019 - 2024. All rights reserved.