2009-12-09 21 views
11

Supponiamo di avere una variabile BOOLEAN all'interno di un/blocco SQL PL in un Modulo Oracle:Valutazione della PL/SQL variabili booleane in Oracle Forms

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

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

Dopo passa tramite questo codice più volte con un debugger, ho determinato che raise_my_error()non viene mai chiamato. Per chiarire:

  • raise_my_error() fa non vengono chiamati se is_viewable = TRUE
  • raise_my_error() fa non vengono chiamati se is_viewable = FALSE

test iniziali suggeriscono che questo comportamento è limitato a PL run/codice SQL all'interno di Oracle Forms e non nel codice PL/SQL eseguito direttamente all'interno del database (sebbene potrei sbagliarmi).

posso ottenere intorno a questo confrontando esplicitamente is_viewable-FALSE:

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

io sono ancora curioso di sapere perchè NOT is_viewable non riporta un risultato TRUE.

Aggiornamento: Sembra che il mio debugger non abbia mostrato valori corretti e che questa domanda non sia più valida. Mi dispiace per quella confusione.

+0

[promemoria amichevole] come utente esperto, credo che abbiate appena dimenticato di accettare una risposta (dcp's o Jeffrey's). –

+0

@AlexanderMalakhov: ho desiderato accettare una risposta in diverse occasioni, ma la domanda sembra essere non risponde ora che il codice sembra funzionare correttamente. A meno che non mi sbagli, nessuna delle due risposte potrebbe spiegare perché 'NOT is_viewable' sarebbe ** sempre ** valutato a' FALSE' (indipendentemente dal valore di 'is_viewable') mentre' is_viewable = FALSE' valuterà o 'TRUE' o ' FALSE', a seconda del valore di 'is_viewable'. Poiché il problema si è interrotto, non posso verificare alcuna risposta. :( –

+0

Capito.Ho avuto simile (wrt "nessuna risposta corretta, non posso verificare") [domanda] (http://stackoverflow.com/questions/2233856/oracle-forms-6i-crashes-with-0xc0000005-at -start-after-installing-patch-19). Poiché c'erano poche probabilità che qualcun altro potesse mai rispondere alla mia Q, ho deciso di accettare * la risposta più utile * (in opposizione alla corretta). il suo tempo e il suo impegno, e per il mio Q non penzolante nell'elenco delle persone senza risposta. Anche se per essere chiari, non ho alcun problema con qualcuno che non segue la mia strategia (anche perché ovviamente stai facendo un ottimo lavoro per la comunità SO) –

risposta

4

A quale valore è impostata la variabile? Capisci che se il valore è nullo, il blocco non verrà mai eseguito. Non sono sicuro se questo è il tuo problema, ma qui è un esempio:

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; 

Naturalmente, io non so come Oracle Forms avrebbero fatto in modo diverso, ma forse è impostare la variabile su null in qualche modo?

+0

Grazie per il suggerimento Ho già capito il problema con i valori di 'NULL'.Tuttavia, ho assistito a questo comportamento (tramite il debugger) con' is_viewable' impostato su 'TRUE' così come' is_viewable' è impostato su 'FALSE'. Ad essere onesti, non avevo provato a vedere cosa sarebbe successo se fosse stato impostato su 'NULL' ... dubito che sarebbe stato di grande aiuto per la situazione –

4

NOT is_viewable restituisce TRUE se e solo se is_viewable è FALSE.

Nel tuo caso, is_viewable è probabilmente impostato su NULL; forse il debugger di Forms ti mostra "FALSE" in questo scenario che causa confusione.

Prova questo codice invece:

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

Prova questo per vedere se cambia qualcosa:

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

Vale la pena ricordare, questo codice nasconde potenzialmente bug. Per esempio. 'myBool: = (sum1 = sum2)', dove 'sum1 = 0' e' sum2 è null'. Uno probabilmente vorrebbe che fosse "True" invece di Null. –

13

possiamo testare questo in SQLPlus per vedere cosa succede in ciascuna delle 3 situazioni (vero , 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; 
/

che 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> 

Quindi l'unico percorso di codice possibile che può produrre l'output previsto è se il valore che va nel condizionale è falso.Se questo non è ciò che stai vedendo o aspettandoti, allora qualcos'altro deve accadere nella tua procedura o come un effetto collaterale.

+0

esplicitamente spiegato .. Grazie – artapart

1

Qual è la versione di Forms?
Ho appena provato seguente codice nel Form Builder 6i e funziona come previsto

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; 

Fa questo lavoro nel proprio ambiente?

Modifica aggiunto null all'esempio.

+0

Sì, la versione dei moduli sarebbe utile. Anche la versione del client Oracle. E del database. Le versioni precedenti di Forms avevano il proprio interprete PL/SQL che potrebbe influire su di te. –

2

È necessario impostare un valore iniziale per is_viewable quando viene dichiarato. Oracle non imposta un valore predefinito per BOOLEANS quando vengono dichiarati. Imposta il valore di BOOLEAN quando viene dichiarato che l'impostazione del valore all'interno del blocco potrebbe non essere sempre l'idea migliore. Se si sta creando una funzione e il blocco non riesce, si può ottenere che una funzione venga restituita senza un valore ma, se dichiarata al di fuori del blocco e si dispone di un gestore di eccezioni, essa catturerebbe e gestirà l'errore. Questa è sempre una buona pratica per impostare il blocco in questo modo.

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 
Problemi correlati