0

有 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

这个怎么做??

4

3 回答 3

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 个值)

于 2012-10-31T18:02:12.380 回答
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;
于 2012-10-31T13:10:41.803 回答
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 语句中使用适当的变量。

于 2012-10-31T15:48:21.673 回答