2009-12-09 90 views
11

Supongamos que tengo una variable BOOLEAN dentro de un bloque PL/SQL en un Formulario de Oracle:Evaluación de las variables booleanas PL/SQL en Oracle Forms

DECLARE 
    is_viewable BOOLEAN; 
BEGIN 
    is_viewable := ...; 

    IF NOT is_viewable THEN 
    raise_my_error(); // pseudo-code 
    END IF; 
END; 

Después de pasar a través de este código varias veces con un depurador, tengo determinó que raise_my_error()nunca se llama. Para aclarar:

  • raise_my_error() hace no se llama si se is_viewable = TRUE
  • raise_my_error() hace no se llama si se is_viewable = FALSE

Las pruebas iniciales sugieren que este comportamiento se limita a PL código se ejecute/SQL dentro de Oracle Forms y no el código PL/SQL ejecutado directamente dentro de la base de datos (aunque podría estar equivocado).

puedo evitar esto mediante la comparación explícita is_viewable a FALSE:

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

todavía estoy curioso por qué NOT is_viewable nunca se evalúa a TRUE.

Actualización: Parece que mi depurador no mostraba los valores correctos y que esta pregunta ya no es válida. Perdón por esa confusión.

+0

[recordatorio útil] como usuario experimentado, supongo que se olvidó de aceptar una respuesta (dcp's o Jeffrey's). –

+0

@AlexanderMalakhov: He querido aceptar una respuesta en varias ocasiones, pero la pregunta parece no responder ahora que el código parece estar ejecutándose correctamente. A menos que esté equivocado, ninguna respuesta podría explicar por qué 'NOT is_viewable' ** siempre ** evalúa a' FALSE' (independientemente del valor de 'is_viewable') mientras que' is_viewable = FALSE' se evaluaría como 'TRUE' o' FALSE', según el valor de 'is_viewable'. Como el problema se detuvo, no puedo verificar ninguna respuesta. :( –

+0

Entendido. Tuve una respuesta similar (wrt "no correcta, no puedo verificar") [pregunta] (http://stackoverflow.com/questions/2233856/oracle-forms-6i-crashes-with-0xc0000005-at -start-after-installation-patch-19). Como había muy poca probabilidad de que alguien más respondiera mi Q, he decidido aceptar la respuesta * más útil * (en lugar de la correcta). Así que para recompensar al hombre por su tiempo y esfuerzo. Y para mi Q no está en la lista de no respondidos. Aunque para ser claro, no tengo ningún problema con alguien que no sigue mi estrategia (más aún porque evidentemente está haciendo un gran trabajo para la comunidad SO) –

Respuesta

4

¿En qué valor se establece la variable? Comprenda que si el valor es nulo, el bloque nunca se ejecutará. No estoy seguro de si eso es su problema, pero aquí es un ejemplo:

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; 

Por supuesto, yo no sé cómo Oracle Forms estarían haciendo de manera diferente, pero tal vez es el establecimiento de la variable en null alguna manera?

+0

Gracias por la sugerencia. Ya entendí el problema con los valores 'NULL'. Sin embargo, he sido testigo de este comportamiento (a través del depurador) con' is_viewable' establecido en 'TRUE', así como' is_viewable' establecido en 'FALSE'. Para ser honesto, no había intentado ver lo que sucedería si se estableciera en 'NULL' ... Dudo que ayudaría mucho a la situación. –

4

NOT is_viewable evalúa a TRUE si y solo si is_viewable es .

En su caso, is_viewable probablemente esté configurado en NULL; quizás el depurador Forms muestra "FALSO" en este escenario y causa confusión.

Prueba este código en su lugar:

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

Prueba esto a ver si cambia nada:

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

Vale la pena mencionar, este código potencialmente oculta errores. P.ej. 'myBool: = (sum1 = sum2)', donde 'sum1 = 0' y' sum2 es nulo'. Uno probablemente querría que esto fuera 'True' en lugar de Null. –

13

podemos probar esto en SQLPlus para ver lo que ocurre en cada una de las 3 situaciones (verdadero , falso, nulo):

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; 
/

que produce:

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> 

Así que la única ruta de código posible que puede producir su salida esperada es si el valor que entra al condicional es falso.Si eso no es lo que está viendo o esperando, entonces algo más debe estar sucediendo en su procedimiento o como un efecto secundario.

+0

muy bien Explicación ... Gracias – artapart

1

¿Cuál es la versión de Forms?
acabo intentado siguiente código en 6i Forms Builder y funciona como se esperaba

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; 

¿Esto funciona en su entorno?

Editar añadió null al ejemplo.

+0

Sí, la versión de formularios sería útil. También la versión del cliente de Oracle. Y de la base de datos. Las versiones anteriores de Forms tenían su propio intérprete PL/SQL que podría afectarlo. –

2

Debe establecer un valor inicial para is_viewable cuando se declara. Oracle no establece un valor predeterminado para BOOLEANS cuando se declaran. Establecer el valor de BOOLEAN cuando se declara establecer el valor dentro del bloque puede no ser siempre la mejor idea. Si está creando una función y el bloque falla, entonces puede obtener una función que se devuelve sin un valor, pero si se declara fuera del bloque y tiene un controlador de excepciones, entonces detectará y manejará el error. Esta es una buena práctica para configurar el bloque de esta manera.

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 
Cuestiones relacionadas