Оценка логических переменных PL/SQL в Oracle Forms
Предположим, что у меня есть переменная BOOLEAN
в блоке PL/SQL в форме Oracle:
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
Исходные тесты показывают, что это поведение ограничено выполнением кода PL/SQL в Oracle Forms, а не кодом PL/SQL, запущенным непосредственно в базе данных (хотя я мог ошибаться).
Я могу обойти это, явно сравнивая is_viewable
с FALSE
:
IF is_viewable = FALSE THEN
raise_my_error();
END IF;
Мне все еще интересно, почему NOT is_viewable
никогда не оценивает TRUE
.
Обновление: Похоже, что мой отладчик не показывал правильные значения и этот вопрос больше недействителен. Прошу прощения за эту путаницу.
Ответы
Ответ 1
Мы можем проверить это в SQLPlus, чтобы узнать, что происходит в каждой из трех ситуаций (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>
Таким образом, единственный возможный путь кода, который может привести к вашему ожидаемому результату, - это если значение, входящее в условное значение, является ложным. Если это не то, что вы видите или ожидаете, тогда что-то еще должно происходить в вашей процедуре или в качестве побочного эффекта.
Ответ 2
Какое значение задается переменной? Поймите, что если значение равно 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 будет делать это по-другому, но, возможно, он каким-то образом установил переменную?
Ответ 3
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;
Ответ 4
Вы должны установить начальное значение для 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
Ответ 5
Попробуйте это, чтобы увидеть, не изменилось ли это:
IF is_viewable THEN
NULL;
ELSE
raise_my_error();
END IF;
Ответ 6
Что такое версия форм?
Я только что попробовал следующий код в 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;
Это работает в вашей среде?
Изменить добавлен нуль, например.