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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1876669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 02:18:33  来源:igfitidea点击:

Evaluation of PL/SQL boolean variables in Oracle Forms

oracleplsqlbooleanoracleforms

提问by Adam Paynter

Suppose I have a BOOLEANvariable within a PL/SQL block in an Oracle Form:

假设我BOOLEAN在 Oracle 表单的 PL/SQL 块中有一个变量:

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()nevergets called. To clarify:

在使用调试器多次单步执行此代码后,我确定raise_my_error()永远不会被调用。澄清:

  • raise_my_error()does notget called if is_viewable = TRUE
  • raise_my_error()does notget called if is_viewable = FALSE
  • raise_my_error()没有被调用,如果is_viewable = TRUE
  • raise_my_error()没有被调用,如果is_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).

初步测试表明,这种行为仅限于在 Oracle Forms 中运行的 PL/SQL 代码,而不是直接在数据库中运行的 PL/SQL 代码(尽管我可能是错的)。

I can get around this by explicitly comparing is_viewableto FALSE:

我可以通过明确比较is_viewable来解决这个问题FALSE

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

I am still curious why NOT is_viewablenever evaluates to TRUE.

我仍然很好奇为什么NOT is_viewable从不评估为TRUE.

Update:It appears that my debugger wasn't showing correct values and that this question is no longer valid. Sorry about that confusion.

更新:看来我的调试器没有显示正确的值,这个问题不再有效。对这种混乱感到抱歉。

回答by Doug Porter

We can test this in SQLPlus to see what happens in each of the 3 situations (true, false, null):

我们可以在 SQLPlus 中对此进行测试,以查看在 3 种情况(真、假、空)中的每一种情况下会发生什么:

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.

因此,可以产生预期输出的唯一可能代码路径是进入条件的值是否为假。如果这不是您所看到或期望的,那么您的程序中一定发生了其他事情或作为副作用。

回答by dcp

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:

变量被设置为什么值?请理解,如果值为 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;

Of course, I don't know how Oracle Forms would be doing it differently, but maybe it's setting the variable to null somehow?

当然,我不知道 Oracle Forms 会有什么不同,但也许它以某种方式将变量设置为 null?

回答by Jeffrey Kemp

NOT is_viewableevaluates to TRUEif and only if is_viewableis FALSE.

NOT is_viewable评估为TRUE当且仅当is_viewableFALSE

In your case, is_viewableis probably being set to NULL; perhaps the Forms debugger shows you "FALSE" in this scenario causing confusion.

在您的情况下,is_viewable可能被设置为NULL; 也许 Forms 调试器在这种情况下会向您显示“FALSE”,从而导致混淆。

Try this code instead:

试试这个代码:

IF NOT is_viewable THEN 
   raise_my_error();
ELSIF is_viewable IS NULL THEN
   raise_another_error();
END IF;

回答by devdar

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.

在声明 is_viewable 时,您必须为其设置初始值。声明 BOOLEANS 时,Oracle 不会为其设置默认值。在声明 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 

回答by Alexander Malakhov

What is the version of Forms ?
I've just tried following code in Forms Builder 6i and it works as expected

表格的版本是什么?
我刚刚在 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;

Does this work in your environment ?

这在您的环境中有效吗?

Editadded null to example.

编辑在示例中添加了 null。

回答by kurosch

Try this to see if it changes anything:

试试这个,看看它是否有任何改变:

IF is_viewable THEN
    NULL;
ELSE
    raise_my_error();
END IF;