在下面的PLSQL函数中,如果不存在“通知方”,我想返回“客户”值。
结果总是返回条件的值“CUSTOMER即使存在”通知方“。为什么?
我使用了同样的功能但involved_party_qual_gid in ('CONSIGNEE', 'CUSTOMER')
它可以很好地产生所需的结果。
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条件。
我只需要知道它为什么不起作用。
感谢所有帮助。谢谢。
答案 0 :(得分:1)
第一个函数的结果将取决于查询返回行的顺序。由于您没有提供order by
子句,因此数据库可以按任何顺序返回行。如果您想要将“NOTIFY PARTY”优先于“CUSTOMER”,您可以在查询中添加以下内容:
order by involved_party_qual_gid desc
你可以接受的其他功能可能是巧合。如果某些东西导致数据库以不同的顺序返回行(例如从备份中恢复,重新组织索引,甚至表中的足够数据来更改计划),它可能会发生变化。
<强>后续强>
通常,当您处理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;
答案 1 :(得分:0)
希望这有效 - 抱歉,如果有任何语法或编译问题,但你明白了 -
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;
或
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;