假设我在Oracle Form中的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()
从不。澄清:
raise_my_error()
,is_viewable = TRUE
会被 调用
如果raise_my_error()
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
。
更新:我的调试器似乎没有显示正确的值,而且此问题不再有效。对此感到抱歉。
答案 0 :(得分:15)
我们可以在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。如果这不是您所看到或期望的,那么您的程序中必须发生其他事情或作为副作用。
答案 1 :(得分:4)
设置的变量值是多少?请理解,如果值为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?
答案 2 :(得分:4)
NOT is_viewable
为TRUE
时, is_viewable
评估为FALSE
。
在您的情况下,is_viewable
可能设置为NULL
;也许Forms调试器在这种情况下显示“FALSE”导致混淆。
请尝试使用此代码:
IF NOT is_viewable THEN
raise_my_error();
ELSIF is_viewable IS NULL THEN
raise_another_error();
END IF;
答案 3 :(得分:2)
声明时,必须为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
答案 4 :(得分:1)
尝试此操作以查看它是否会发生任何变化:
IF is_viewable THEN
NULL;
ELSE
raise_my_error();
END IF;
答案 5 :(得分:1)
表格的版本是什么?
我刚刚尝试在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添加到示例。