评估Oracle Forms中的PL / SQL布尔变量

时间:2009-12-09 20:30:17

标签: oracle plsql boolean oracleforms

假设我在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_viewableFALSE比较来解决这个问题:

IF is_viewable = FALSE THEN
  raise_my_error();
END IF;

我仍然很好奇为什么NOT is_viewable永远不会评估为TRUE

更新:我的调试器似乎没有显示正确的值,而且此问题不再有效。对此感到抱歉。

6 个答案:

答案 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_viewableTRUE时,

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添加到示例。