简体   繁体   English

程序出现ora-01422错误

[英]ora-01422 error by a procedure

Below code throwing ORA-01422 error. 下面的代码抛出ORA-01422错误。 As my code uses select ... into I come to know it is fetching more than one row from the table but how can I overcome this by eliminating select into statement. 当我的代码使用select ... into我知道它正在从表中获取多个行,但是如何通过消除select into语句来克服这一点。 Here is the code: 这是代码:

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;

How can I rewrite the code to resolve ORA-01422 error? 如何重写代码以解决ORA-01422错误?

In oracle, you can keep the select into statement and limit the number of rows using ROWNUM: 在oracle中,可以保留select into语句并使用ROWNUM限制行数:

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

First, you need to change exception handling logic: 首先,您需要更改异常处理逻辑:

  • enclose in begin ... exception ... end only part that really can through exception; 封闭在begin ... exception ... end只有真正可以通过异常的部分;
  • handle too_many_rows exception 处理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;

After refactoring you need to answer a question about what really must be performed in situations when more than one row found and handle it according to nature of implemented task. 重构后,您需要回答一个问题,即在发现多个行并根据已实现任务的性质处理该行的情况下真正必须执行什么操作。

If you worried about method that you can use to detect presence of values and determine it's count then you may look at this question on StackOverflow . 如果您担心可用于检测值的存在并确定其计数的方法,则可以在StackOverflow上查看此问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM