OracleフォームのPL/SQLブロック内にBOOLEAN
変数があるとします。
_DECLARE
is_viewable BOOLEAN;
BEGIN
is_viewable := ...;
IF NOT is_viewable THEN
raise_my_error(); // pseudo-code
END IF;
END;
_
デバッガーでこのコードを数回実行した後、raise_my_error()
neverが呼び出されることがわかりました。明確にするために:
raise_my_error()
はnot _is_viewable = TRUE
_の場合に呼び出されますraise_my_error()
はnot _is_viewable = FALSE
_の場合に呼び出されます初期のテストでは、この動作はOracle Forms内で実行されるPL/SQLコードに限定されており、データベース内で直接実行されるPL/SQLコードには限定されていません(ただし、間違っている可能性があります)。
_is_viewable
_とFALSE
を明示的に比較することで、これを回避できます。
_IF is_viewable = FALSE THEN
raise_my_error();
END IF;
_
_NOT is_viewable
_がTRUE
に評価されない理由を私はまだ知りたいです。
pdate:デバッガーが正しい値を表示しておらず、この質問は無効になっているようです。その混乱については申し訳ありません。
これをSQLPlusでテストして、3つの状況(true、false、null)のそれぞれで何が起こるかを確認できます。
set serveroutput on
declare
true_value boolean := true;
false_value boolean := false;
null_value boolean;
begin
if not true_value then --Should not pass
dbms_output.put_line('True Value');
end if;
if not false_value then --Should pass
dbms_output.put_line('False Value');
end if;
if null_value is null then --Just to make sure it is null
dbms_output.put_line('Null Value is Null');
end if;
if not null_value then --Should not pass
dbms_output.put_line('Null Value');
end if;
end;
/
生成されるもの:
SQL> set serveroutput on
SQL>
SQL> declare
2 true_value boolean := true;
3 false_value boolean := false;
4 null_value boolean;
5 begin
6
7 if not true_value then --Should not pass
8 dbms_output.put_line('True Value');
9 end if;
10
11 if not false_value then --Should pass
12 dbms_output.put_line('False Value');
13 end if;
14
15 if null_value is null then --Just to make sure it is null
16 dbms_output.put_line('Null Value is Null');
17 end if;
18
19 if not null_value then --Should not pass
20 dbms_output.put_line('Null Value');
21 end if;
22 end;
23 /
False Value
Null Value is Null
PL/SQL procedure successfully completed.
SQL>
したがって、期待される出力を生成できる唯一の可能なコードパスは、条件に入る値がfalseの場合です。それがあなたが見ているものでも期待しているものでもない場合は、あなたの手順でまたは副作用として何か他のことが起こっているはずです。
NOT is_viewable
は、is_viewable
がTRUE
の場合に限り、FALSE
と評価されます。
あなたの場合、is_viewable
はおそらくNULL
に設定されています。おそらくフォームデバッガーは、このシナリオで「FALSE」を表示して混乱を引き起こします。
代わりにこのコードを試してください:
IF NOT is_viewable THEN
raise_my_error();
ELSIF is_viewable IS NULL THEN
raise_another_error();
END IF;
変数にはどの値が設定されていますか?値がnullの場合、ブロックは実行されないことを理解してください。それがあなたの問題かどうかはわかりませんが、ここに例があります:
DECLARE
is_viewable BOOLEAN;
BEGIN
IF NOT is_viewable
THEN
/* this won't execute */
dbms_output.put_line('nope');
END IF;
IF is_viewable
THEN
/* neither will this */
dbms_output.put_line('nope');
END IF;
END;
もちろん、Oracle Formsがどのように異なる方法で実行するかはわかりませんが、変数を何らかの方法でnullに設定しているのでしょうか。
Is_viewableの宣言時に、初期値を設定する必要があります。 Oracleは、宣言時にBOOLEANSのデフォルト値を設定しません。ブロック内に値を設定することが宣言されている場合は、BOOLEANの値を設定することが常に最良の方法であるとは限りません。関数を作成していてブロックが失敗した場合、値なしで関数が返されることがありますが、ブロックの外側で宣言されており、例外ハンドラーがある場合は、エラーをキャッチして処理します。これは、常にこの方法でブロックを設定するための良い方法です。
DECLARE
bTest BOOLEAN := FALSE;
BEGIN
--in your test check for the most likely thing that would happen
--if bTest would in most instances evaluate to be FALSE then that should be your check
IF NOT bTest THEN
MESSAGE('True Passed');
ELSE
MESSAGE('False Passed');
END IF;
--in the event that an exception occurs or the block fails
--the function would still return a value
EXCEPTION WHEN NO_DATA_FOUND THEN
bTest := FALSE;
WHEN OTHERS THEN
bTest := FALSE;
END
これを試して、何かが変わるかどうかを確認します。
IF is_viewable THEN
NULL;
ELSE
raise_my_error();
END IF;
フォームのバージョンは何ですか?
Forms Builder 6iで次のコードを試したところ、期待どおりに動作しました
DECLARE
bTest BOOLEAN;
BEGIN
bTest := FALSE;
IF NOT bTest THEN
MESSAGE('NOT FALSE passed');
PAUSE;
END IF;
bTest := TRUE;
IF bTest THEN
MESSAGE('TRUE passed');
PAUSE;
END IF;
bTest := NULL;
IF bTest OR (NOT bTest) THEN
MESSAGE('You will never see this message');
PAUSE;
END IF;
END;
これはあなたの環境で動作しますか?
編集例にnullを追加しました。