If statement 为If条件PLSQL返回的值错误

If statement 为If条件PLSQL返回的值错误,if-statement,plsql,cursor,compare,If Statement,Plsql,Cursor,Compare,在下面的PLSQL函数中,如果不存在“通知方”,我希望返回“Customer”值 结果总是返回条件“CUSTOMER”的值,即使存在“Notify Party”。这是为什么? 我曾使用过相同的功能,但在(‘收货人’、‘客户’)中使用了参与方\u qual\u gid 它工作得很好,产生了所需的结果 function getNotifyPartyOrCustomer(orderID varchar2) return varchar2 is NameResult varchar2(100); C

在下面的PLSQL函数中,如果不存在“通知方”,我希望返回“Customer”值

结果总是返回条件“CUSTOMER”的值,即使存在“Notify Party”。这是为什么? 我曾使用过相同的功能,但在(‘收货人’、‘客户’)中使用了
参与方\u qual\u gid
它工作得很好,产生了所需的结果

function getNotifyPartyOrCustomer(orderID varchar2) return varchar2

is
NameResult varchar2(100);

CURSOR c_involved_party is
  select involved_party_contact_gid, involved_party_qual_gid
    from order_release_inv_party
   where involved_party_qual_gid in ('NOTIFY PARTY', 'CUSTOMER')
     and order_release_gid = orderID;
begin

for i in c_involved_party loop

  if i.involved_party_qual_gid = 'NOTIFY PARTY' then
    NameResult := i.involved_party_contact_gid;
    return(NameResult);

  elsif i.involved_party_qual_gid = 'CUSTOMER' then
    NameResult := i.involved_party_contact_gid;
    return(NameResult);
  end if;
 end loop;

end;
我编写了两个可产生相同结果的备选函数:

1-职能1

function getNotifyPartyOrCustomer(orderID varchar2) return varchar2

 is
  NameResult varchar2(100);

 begin

   select coalesce((select involved_party_contact_gid
                  from order_release_inv_party
                 where involved_party_qual_gid = 'NOTIFY PARTY'
                   and order_release_gid = orderID),

                (select involved_party_contact_gid
                   from order_release_inv_party
                  where involved_party_qual_gid = 'CUSTOMER'
                    and order_release_gid = orderID), 

                'NO DATA'

                ) AS NAME
   INTO NameResult

   from DUAL;

  return NameResult;
end;
2-功能2

function getNotifyPartyOrCustomer(orderID varchar2) return varchar2

 is
   NameResult varchar2(100);


 begin

    select involved_party_contact_gid
    INTO NameResult
    from order_release_inv_party
   where involved_party_qual_gid in ('NOTIFY PARTY')
     and order_release_gid = orderID;

   return(NameResult);

     exception WHEN NO_DATA_FOUND THEN

      select involved_party_contact_gid
        into NameResult
        from order_release_inv_party
       where involved_party_qual_gid in ('CUSTOMER')
         and order_release_gid = orderID;   



 return(NameResult);
end;
但我对这两个函数不满意,因为首先,从性能角度来看,我不认为必须从同一个表中检索两次有什么意义,因为我可以在一次检索中得到结果并对其执行逻辑,其次,因为我需要其他逻辑的if条件

我只想知道为什么它不起作用


感谢所有帮助。谢谢。

第一个函数的结果将取决于查询返回行的顺序。由于您没有提供
order by
子句,数据库可以按任何顺序返回行。如果您想将“通知方”优先于“客户”,可以在查询中添加以下内容:

相关方的订单\u质量\u gid说明

您的另一个工作正常的函数可能是巧合。如果有什么原因导致数据库以不同的顺序返回行(例如从备份中恢复、重新组织索引,甚至是表中的数据刚好足以更改计划),则该函数可能会更改


跟进

通常,在处理SQL时,如果在结果集上进行迭代,则采用的方法很差。数据库引擎非常擅长处理基于集合的问题,因此通常最好让引擎处理尽可能多的工作

在这种情况下,看起来您并不真正关心每一行的结果:实际上您只需要包含“NOTIFY PARTY”的第一行,如果不存在这样的记录,则需要包含“CUSTOMER”的第一行“。假设结果集返回500行。当您只关心1行的值时,为什么要迭代所有500行?如果我编写这个函数,我将完全失去迭代:

function getNotifyPartyOrCustomer(orderID varchar2) return varchar2 is
NameResult varchar2(100);

CURSOR c_involved_party is
  select involved_party_contact_gid
    from order_release_inv_party
   where involved_party_qual_gid in ('NOTIFY PARTY', 'CUSTOMER')
     and order_release_gid = orderID
   order by involved_party_qual_gid desc;

v_contact_gid order_release_inv_party.involved_party_contact_gid%type;
begin

open c_involved_party;
fetch c_involved_party into v_contact_gid;
close c_involved_party;

return v_contact_gid;

end getNotifyPartyOrCustomer;

希望这能起作用-抱歉,如果出现语法或编译问题,但是您明白了-

CREATE OR REPLACE FUNCTION getnotifypartyorcustomer (orderid VARCHAR2)
   RETURN VARCHAR2
IS
   nameresult   VARCHAR2 (100);

   CURSOR c_involved_party
   IS
      SELECT CASE
                WHEN involved_party_contact_gid =
                                         'CUSTOMER'
                   THEN involved_party_qual_gid
                ELSE NULL
             END involved_party_qual_gid_a,
             CASE
                WHEN involved_party_contact_gid =
                                     'NOTIFY PARTY'
                   THEN involved_party_qual_gid
                ELSE NULL
             END involved_party_qual_gid_b
        FROM order_release_inv_party
       WHERE involved_party_qual_gid IN ('NOTIFY PARTY', 'CUSTOMER')
         AND order_release_gid = orderid;
BEGIN
   FOR i IN c_involved_party
   LOOP
      nameresult :=
         NVL (NVL (i.involved_party_qual_gid_a, i.involved_party_qual_gid_b),
              'NONE'
             );
   END LOOP;

   RETURN (nameresult);
EXCEPTION WHEN OTHERS 
    RETURN nameresult;
    -- or RAISE if You Want
END;


非常感谢艾伦,一个简单的回答,我就是看不出来。如果你不介意的话,还有其他更好的方法来实现这个功能吗?或者这足够好了。非常感谢,我很感激。另外,我正在尝试一种方法,在不必依赖查询返回行的顺序的情况下遍历列表。i、 e.在应用if条件之前,对整个列表进行循环,有什么建议吗?再次感谢Allan的后续工作,衷心感谢。:)正是我需要的!谢谢Sandeep,非常感谢。。。。。这也是另一种方法,它让我敞开了心扉去做它…再次感谢
CREATE OR REPLACE FUNCTION getnotifypartyorcustomer (orderid VARCHAR2)
RETURN VARCHAR2
IS
   nameresult   VARCHAR2 (100);
BEGIN
SELECT NVL (NVL (involved_party_qual_gid_a, involved_party_qual_gid_b),'NONE')
  INTO nameresult
  FROM (SELECT CASE
                  WHEN involved_party_contact_gid =
                                         'CUSTOMER'
                     THEN involved_party_qual_gid
                  ELSE NULL
               END involved_party_qual_gid_a,
               CASE
                  WHEN involved_party_contact_gid =
                                     'NOTIFY PARTY'
                     THEN involved_party_qual_gid
                  ELSE NULL
               END involved_party_qual_gid_b
          FROM order_release_inv_party
         WHERE involved_party_qual_gid IN ('NOTIFY PARTY', 'CUSTOMER')
           AND order_release_gid = orderid)
       );

   RETURN (nameresult);
EXCEPTION WHEN OTHERS 
    RETURN NULL ;
    -- RETURN 'NONE' ;
END;