有4个参数.material,Suppliernbr,Suppliername,Materail代码。我的查询是用户是否在一个参数中输入任何一个参数,我需要输入循环。
For Eg:
P_suppname='stack'
p_matrl='NULL'
p_suppnbr:=NULL
P_mtrlcde='NULL' I can go inside
但是如果
P_suppname=NULL
p_matrl=211
p_suppnbr:=43443443
P_mtrlcde='NULL' I shouldnt go.
另外
P_suppname=NULL
p_matrl='211;2322'
p_suppnbr:=NULL
P_mtrlcde='NULL' I should nt go
怎么做?
答案 0 :(得分:0)
计算每个参数中;
的数量,使用nvl
在空值上计算零:
select
nvl( length('211;2322') - length(replace('211;2322', ';', '')) +1, 0), -->2
nvl( length('211;2322;34') - length(replace('211;2322;34', ';', '')) +1, 0), -->3
nvl( length(Null) - length(replace(Null, ';', '')) +1, 0) -->0
from dual
在IF
条件下使用:
IF ( nvl( length(p_suppname) - length(replace(p_suppname, ';', '')) +1, 0)
+ nvl( length(p_matrl) - length(replace(p_matrl, ';', '')) +1, 0)
+ nvl( length(p_suppnbr) - length(replace(p_suppnbr, ';', '')) +1, 0)
+ nvl( length(p_mtrlcde) - length(replace(p_mtrlcde, ';', '')) +1, 0)
) = 1 THEN
--LOOP
END IF;
答案 1 :(得分:0)
对于明显的解决方案,有很多话要说。毕竟,大自然给了我们cut'n'paste,而不是使用它?
IF NOT ( (P_suppname is NOT NULL and p_matrl is null and p_suppnbr is NULL and P_mtrlcde is NULL )
or (P_suppname is NULL and p_matrl is NOT NULL and p_suppnbr is NULL and P_mtrlcde is NULL )
or (P_suppname is NULL and p_matrl is NULL and p_suppnbr is NOT NULL and P_mtrlcde is NULL )
or (P_suppname is NULL and p_matrl is NULL and p_suppnbr is NULL and P_mtrlcde is NOT NULL ) )
THEN
raise_application_error(-20000, 'wrong number of parameters');
ELSE
.....
这具有表达其意图的巨大好处:它清楚地检查一个且仅一个参数包含值。其他解决方案可能会更加吵闹,但它们会妨碍人们理解他们想要做的事情。
当然,发布的代码会带来一些复杂性。接口显然允许调用程序传递字符串'NULL'而不是传递NULL。此外,尽管p_matrl
似乎是一个数字,但它被定义为varchar2,因此调用程序可以传递废话,如'211; 2322'。
解决这些缺陷的正确方法是修复API,使其不接受这样的废话。这是界面设计者的特权,用于指定调用程序应遵守的契约。换句话说,如果调用程序传递'NULL'而不是NULL,则拒绝它们的参数。将p_matrl
的数据类型更改为数字。
但是,一旦API在野外和使用中,处理垃圾的负担落在界面设计师的肩上。他们必须包含额外的验证码。这是规格不佳的代价。不幸的是,它通常不是由原始人承担的:设计者的罪行是在维护者身上访问的。
无论如何,要解决这些问题,我们需要声明局部变量并检查/传递参数值。例如:
if p_matrl = 'NULL'
then
l_matrl := null;
else
l_matrl := to_number(p_matrl);
end if;
对所有参数进行验证,并在上面的IF语句中使用适当的变量。
答案 2 :(得分:0)
虽然我无法想象会产生这样一个要求的接口类型(或NULL
和'NULL'
的有效值),但这是我如何处理它:
DECLARE
cnt NUMBER;
BEGIN
SELECT DECODE(p_suppname, 'NULL',0, DECODE(INSTR(p_suppname,';'),NULL,0,0,1,0)) +
DECODE(p_matrl, 'NULL', 0, DECODE(INSTR(p_suppname,';'),NULL,0,0,1,0)) +
DECODE(p_suppnbr, NULL, 0, 1) +
DECODE(p_mtrlcde, 'NULL', 0, DECODE(INSTR(p_suppname,';'),NULL,0,0,1,0)) into cnt
from dual;
IF cnt = 1 THEN
LOOP
/* do whatever here */
END LOOP;
END IF;
END;
我假设p_suppnbr是一个数字,其他所有都是字符串 我还假设任何参数都可以为NULL,并且字符串'NULL'等效于NULL值 (我也隐含地假设任何带有分号的参数至少包含2个值)