问题
Suppose I have a BOOLEAN
variable within a PL/SQL block in an Oracle Form:
DECLARE
is_viewable BOOLEAN;
BEGIN
is_viewable := ...;
IF NOT is_viewable THEN
raise_my_error(); // pseudo-code
END IF;
END;
After stepping through this code several times with a debugger, I have determined that raise_my_error()
never gets called. To clarify:
raise_my_error()
does not get called ifis_viewable = TRUE
raise_my_error()
does not get called ifis_viewable = FALSE
Initial tests suggest that this behavior is limited to PL/SQL code run within Oracle Forms and not PL/SQL code run directly within the database (although I could be wrong).
I can get around this by explicitly comparing is_viewable
to FALSE
:
IF is_viewable = FALSE THEN
raise_my_error();
END IF;
I am still curious why NOT is_viewable
never evaluates to TRUE
.
Update: It appears that my debugger wasn't showing correct values and that this question is no longer valid. Sorry about that confusion.
回答1:
We can test this in SQLPlus to see what happens in each of the 3 situations (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;
/
Which produces:
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>
So the only possible code path that can produce your expected output is if the value going into the conditional is false. If that is not what you are seeing or expecting then something else must be happening in your procedure or as a side effect.
回答2:
What value is the variable being set to? Do understand that if the value is null, the the block will never execute. I'm not sure if that's your problem, but here's an example:
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;
Of course, I don't know how Oracle Forms would be doing it differently, but maybe it's setting the variable to null somehow?
回答3:
NOT is_viewable
evaluates to TRUE
if and only if is_viewable
is FALSE
.
In your case, is_viewable
is probably being set to NULL
; perhaps the Forms debugger shows you "FALSE" in this scenario causing confusion.
Try this code instead:
IF NOT is_viewable THEN
raise_my_error();
ELSIF is_viewable IS NULL THEN
raise_another_error();
END IF;
回答4:
You must set an initial value for is_viewable when it is declared. Oracle does not set a default value for BOOLEANS when they are declared. Set the value of the BOOLEAN when it is declared setting the value inside the block may not always be the best idea. If you are creating a function and the block fails then you may get a function being returned without a value but if declared outside the block and you have an exception handler then it would catch and handle the error. This is always a good practice to set up the block in this manner.
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
回答5:
Try this to see if it changes anything:
IF is_viewable THEN
NULL;
ELSE
raise_my_error();
END IF;
回答6:
What is the version of Forms ?
I've just tried following code in Forms Builder 6i and it works as expected
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;
Does this work in your environment ?
Edit added null to example.
来源:https://stackoverflow.com/questions/1876669/evaluation-of-pl-sql-boolean-variables-in-oracle-forms