Supposons que j'ai une variable BOOLEAN
dans un bloc PL/SQL dans une forme Oracle:
DECLARE
is_viewable BOOLEAN;
BEGIN
is_viewable := ...;
IF NOT is_viewable THEN
raise_my_error(); // pseudo-code
END IF;
END;
Après avoir parcouru ce code plusieurs fois avec un débogueur, j'ai déterminé que raise_my_error()
jamais est appelée. Clarifier:
raise_my_error()
fait non est appelé si is_viewable = TRUE
raise_my_error()
fait non est appelé si is_viewable = FALSE
Les premiers tests suggèrent que ce comportement est limité au code PL/SQL exécuté dans les formulaires Oracle et non de code PL/SQL exécuté directement dans la base de données (bien que je puisse me tromper).
Je peux me contenter de comparer explicitement is_viewable
À FALSE
:
IF is_viewable = FALSE THEN
raise_my_error();
END IF;
Je suis toujours curieux pourquoi NOT is_viewable
Ne jamais évaluer à TRUE
.
Mise à jour : Il apparaît que mon débogueur n'apparaissait pas les valeurs correctes et que cette question n'est plus valide. Désolé pour cette confusion.
Nous pouvons tester cela dans SQLPlus pour voir ce qui se passe dans chacune des 3 situations (vrai, faux, 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;
/
Qui produit:
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>
Donc, le seul chemin de code possible pouvant produire votre sortie attendue est si la valeur dans le conditionnel est fausse. Si ce n'est pas ce que vous voyez ou attendez, alors quelque chose d'autre doit se produire dans votre procédure ou comme effet secondaire.
NOT is_viewable
Évalue à TRUE
si et seulement si is_viewable
est FALSE
.
Dans ton cas, is_viewable
est probablement défini sur NULL
; Peut-être que le débogueur des formulaires vous montre "False" dans ce scénario, ce qui provoque une confusion.
Essayez ce code à la place:
IF NOT is_viewable THEN
raise_my_error();
ELSIF is_viewable IS NULL THEN
raise_another_error();
END IF;
Quelle valeur la variable est-elle réglée? Comprenez que si la valeur est null, le bloc ne s'exécutera jamais. Je ne sais pas si c'est votre problème, mais voici un exemple:
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;
Bien sûr, je ne sais pas comment les formes oracles le feraient différemment, mais peut-être que cela définit la variable à NULL en quelque sorte?
Vous devez définir une valeur initiale pour IS_Viewable lorsqu'il est déclaré. Oracle ne définit pas une valeur par défaut pour les booléens lorsqu'ils sont déclarés. Définissez la valeur du booléen lorsqu'il est déclaré définir la valeur à l'intérieur du bloc peut ne pas toujours être la meilleure idée. Si vous créez une fonction et que le bloc échoue, vous pouvez obtenir une fonction renvoyée sans valeur mais si elle est déclarée à l'extérieur du bloc et que vous avez un gestionnaire d'exception, il attraperait et gérerait l'erreur. C'est toujours une bonne pratique pour configurer le bloc de cette manière.
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
Essayez ceci pour voir si cela change quelque chose:
IF is_viewable THEN
NULL;
ELSE
raise_my_error();
END IF;
Quelle est la version des formulaires?
[.____] Je viens d'essayer de suivre le code dans les formulaires Builder 6i et cela fonctionne comme prévu
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;
Est-ce que cela fonctionne dans votre environnement?
Edit Ajout de NULL à l'exemple.