ora-01422程序错误

时间:2014-01-09 12:32:06

标签: oracle plsql

下面的代码抛出ORA-01422错误。当我的代码使用select ... into时,我发现它从表中获取了多行但是如何通过消除select into语句来克服这一行。这是代码:

PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN

Declare
  M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
  M_Transaction_Cd   U_Transaction_Master.Transaction_Cd%Type;

  T_Transaction_Cd   U_Transaction_Master.Transaction_Cd%Type;
Begin

  Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
  Where Transaction_Name = M_Transaction_Name ;
  Begin
    Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions  
    Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
    Inst_Cd = :Global.Company_Cd And
    To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';

    If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then
         DECLARE
         id FormModule; 
       BEGIN
         id := Find_Form(M_Transaction_Name); --<Replace your form name>--
         IF Id_Null(id) THEN
             Call_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
         ELSE
             Go_Form(Id) ;
         END IF ;
       END ;       
    Elsif Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'OPEN_FORM' Then
              Open_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
    Elsif Transaction_Type = 'REPORT' And Upper(Form_Open_Type) = 'RUN_PRODUCT' Then
          Declare
            Pl_Id ParamList;
          Begin 
            Pl_Id := Get_Parameter_List('tmpdata'); 
            IF NOT Id_Null(Pl_Id) THEN 
               Destroy_Parameter_List( Pl_Id ); 
            END IF; 
            Pl_Id := Create_Parameter_List('tmpdata'); 

            ADD_Parameter(pl_id,'Inst_Cd',TEXT_PARAMETER,:GLOBAL.Company_Cd);
            ADD_Parameter(pl_id,'Ac_Year_Cd',TEXT_PARAMETER,:GLOBAL.Ac_Year_Cd);
            ADD_Parameter(Pl_Id,'INST_NAME',TEXT_PARAMETER, :Global.Company_name);
            ADD_Parameter(Pl_Id,'ADDRESS',TEXT_PARAMETER, :Global.Address);
            ADD_Parameter(pl_id,'FOOTER',TEXT_PARAMETER,:GLOBAL.Footer);

            Run_Product(REPORTS,:Global.Reports_Path||M_Transaction_Name, SYNCHRONOUS, RUNTIME,
                        FILESYSTEM, Pl_Id, NULL); 
          End;
    End If;

  Exception
    When No_Data_Found Then
         Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
         Raise Form_Trigger_Failure;
  End;

Exception
  When No_Data_Found Then
       Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
       Raise Form_Trigger_Failure;
End;

END;

如何重写代码以解决ORA-01422错误?

2 个答案:

答案 0 :(得分:0)

在oracle中,您可以保留select into语句并使用ROWNUM限制行数:

Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
  Where Transaction_Name = M_Transaction_Name 
    and ROWNUM < 2;

答案 1 :(得分:0)

首先,您需要更改异常处理逻辑:

  • 只包含begin ... exception ... end部分内容 通过例外;
  • 处理too_many_rows例外

PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN

Declare
  M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
  M_Transaction_Cd   U_Transaction_Master.Transaction_Cd%Type;

  T_Transaction_Cd   U_Transaction_Master.Transaction_Cd%Type;
Begin

  --  1st select with error analysis
  begin
    Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
    Where Transaction_Name = M_Transaction_Name ;
  exception
    when No_Data_Found then begin
       Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
       Raise Form_Trigger_Failure;
      end;
    when too_many_rows then begin 
       -- What really must be done in this case?
       Message('There are too many Transaction Cd's with passed name In Transaction Master, Please Contact Administrator...');
       Raise Form_Trigger_Failure;
    end;
  end;

  -- 2nd select with error analysis
  begin
    Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions  
    Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
          Inst_Cd = :Global.Company_Cd And
          To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';
  Exception
    When No_Data_Found Then begin
         Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
         Raise Form_Trigger_Failure;
      end;
    When too_many_rows Then begin
         -- What really must be done in this case?
         Message('Sorry..., there are some misconfiguration in Authorization Settings For : '||M_Transaction_Cd||' Transaction Code. Please contact Administrator.');
         Raise Form_Trigger_Failure;
      end;
  End;

  If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then

     ---[... all other code skipped ...]---

  End If;


END;

重构后,你需要回答一个问题,即在发现多行的情况下必须执行什么,并根据实现的任务的性质处理它。

如果您担心可以用来检测值的存在并确定其数量的方法,那么您可以查看this question on StackOverflow