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

明白な解決策を支持して言われることがたくさんあります。結局のところ、自然は私たちにカットアンドペーストを与えてくれましたが、それを使用していませんか?

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
    .....

これには、その意図を表現するという大きな利点があります。1つだけのパラメーターに値が含まれていることを明確にチェックしています。他の解決策はもっと気まぐれかもしれませんが、彼らがやろうとしていることを理解する人々の能力を妨げるでしょう。


もちろん、投稿されたコードはいくつかの複雑さをもたらします。このインターフェースでは、呼び出し元のプログラムが単に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 に答える
0

null のゼロをカウントするため;に使用して、各パラメーターの数をカウントします。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

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 に答える