to:goustong 
imp_fee表的结构
create table IMP_FEE
(
    FEE_ITEM_NO                  CHAR(4)                not null,
    IMPORT_SEQ                   NUMBER(8)              not null,
    STANDARD_FEE                NUMBER(8)              null    ,
    REAL_FEE                     NUMBER(8)              null    ,
    OVER_FEE                     NUMBER(8)              null    ,
    INVOICE_FEE                  NUMBER(8)              null    ,
    RATE                         NUMBER(3)              null    ,
    constraint PK_IMP_FEE primary key (FEE_ITEM_NO, IMPORT_SEQ)
)

解决方案 »

  1.   

    to:goustong 
    imp_fee表的结构
    create table IMP_FEE
    (
        FEE_ITEM_NO                  CHAR(4)                not null,
        IMPORT_SEQ                   NUMBER(8)              not null,
        STANDARD_FEE                NUMBER(8)              null    ,
        REAL_FEE                     NUMBER(8)              null    ,
        OVER_FEE                     NUMBER(8)              null    ,
        INVOICE_FEE                  NUMBER(8)              null    ,
        RATE                         NUMBER(3)              null    ,
        constraint PK_IMP_FEE primary key (FEE_ITEM_NO, IMPORT_SEQ)
    )
    我想知道的是后面那段异常处理是否正确,能否返回执行出错的信息。即该段代码能否起作用。可有别的写法。我用delphi做前台开发,执行时有错通过on_ErrCode返回值时0,ov_ErrMsg返回值是空。但确实出错了。去掉exception之后的就有系统给出正确的错误信息,号码。
      

  2.   

    去掉 raise,因为 raise 之后,存储过程被强行退出,不会有任何返回值
      

  3.   

    我的客户端在EXCEPTION 里处理这些返回的信息。需要引发一个异常,才能触发客户端的错误处理。如果去掉raise,该如何在数据库服务器发消息引发客户端的错误处理。
      

  4.   

    你要在客户端引发异常,可以根据存储过程的返回值,来确定是否触发异常。
    你应该在 exception 前面设定“正常标志”
    ...
    ...
        on_ErrCode := 0;
        ov_ErrMsg := '';
      exception
    ...
    ...
      
      

  5.   

    在数据库中触发异常提交给前台程序。
    raise_application_error(error_number, message[, {TRUE | FALSE}]);
    看一下oracle的帮助。
    前台处理:
    procedure Handle_Exception(E: Exception);
    var
        errcode :Integer;
    begin
        if (E is EDBEngineError) then
        begin
            if ( E as EDBEngineError ).ErrorCount>1 then
                Handle_DBEngine_Error( E as EDBEngineError ) --自定义处理
            else
            begin
                errcode :=(E as EDBEngineError).Errors[0].Errorcode;
                case errcode of
                eDetailsExist:
                  begin
                    Show_Error('主表不能删除,请先删除从表记录。');
                    Abort;
                  end;
                eKeyViol:
                  begin
                    Show_Error('关键字重复,不能插入此记录。');
                    Abort;
                  end;
                else
                    Application.ShowException(E);
                end;        end;
        end
        else if (E is EDatabaseError) then// 处理 EDatabaseError
        begin
            Handle_Database_Error( E as EDatabaseError ); --自定义
        end
        else     // 处理一般错误
        begin
            Application.ShowException(E);
        end;
    end;procedure Handle_DBEngine_Error(E :EDBEngineError);
    var
        str_Err :String;
        Pos_B,Pos_E :Integer;
        ErrorCode :WORD;
    begin
        case E.Errors[1].NativeError of
        20004: --假设 oracle 提交的是-20004错误号
          begin
              str_Err := E.Errors[1].Message;
              Show_Error(str_Err);
          end;
        else
          begin
              case E.Errors[0].SubCode of
                  ERRCODE_KEYVIOL: // Primary Key, Unique Index
                      Show_Error( E.Errors[1].Message );
                  ERRCODE_REQDERR: // Not Null
                      Show_Error( E.Errors[1].Message );
                  ERRCODE_FORIEGNKEYERR: // Foreign Key Not Found
                      Show_Error( E.Errors[1].Message );
                  ERRCODE_DETAILRECORDSEXIST: // Foreign Key Has Child
                      Show_Error( E.Errors[1].Message );
              else
                  Application.ShowException(E);
              end;{case}
          end;
        end;
    end;