2008-10-09 5 views
4

Howdy. Учитывайте следующее:PL/SQL Оценочный заказ

SQL> DECLARE 
    2  b1 BOOLEAN; 
    3  b2 BOOLEAN; 
    4  FUNCTION checkit RETURN BOOLEAN IS 
    5  BEGIN 
    6  dbms_output.put_line('inside checkit'); 
    7  RETURN TRUE; 
    8  END checkit; 
    9 
10  PROCEDURE outp(n VARCHAR2, p BOOLEAN) IS 
11  BEGIN 
12  IF p THEN 
13   dbms_output.put_line(n||' is true'); 
14  ELSE 
15   dbms_output.put_line(n||' is false'); 
16  END IF; 
17  END; 
18 BEGIN 
19  b1 := TRUE OR checkit; 
20  outp('b1',b1); 
21  b2 := checkit OR TRUE; 
22  outp('b2',b2); 
23 END; 
24/

b1 is true 
inside checkit 
b2 is true 

PL/SQL procedure successfully completed 

SQL> 

Обратите внимание, что результаты операторов OR зависят от порядка. Если сначала поместить вызов функции, тогда функция выполняется независимо от значения другого термина. Похоже, что инструкция OR вычисляется слева направо до получения TRUE, после чего обработка останавливается и результат ИСТИНА.

Мой вопрос в том, на что я могу положиться? Или это поведение может измениться в будущих выпусках PL/SQL? Если это может измениться, есть ли способ заставить функцию оцениваться, на которую я могу положиться (без создания другой переменной и использования отдельной инструкции присваивания)?

ответ

8

Да. PL/SQL выполняет short circuit evaluation логических выражений слева направо.

+0

Perfecto. Только то, что я искал! – DCookie 2008-10-09 16:42:00

+0

Мой google для «pl/sql complete boolean evaluation» дал мне точно такую ​​же ссылку. – JosephStyons 2008-10-09 16:42:23

1

Если это может измениться, существует ли способ заставить функцию оцениваться, на которую я могу положиться (без создания другой переменной и использования отдельной инструкции присваивания)?

Если вам требуется, чтобы функция была просветлена, даже если это логически избыточно, это означает, что она делает что-то другое, кроме как просто возвращает TRUE или FALSE, например. возможно, обновляет таблицу. Не считается хорошей практикой для функций PL/SQL иметь такие «побочные эффекты».

1

В документации указывается, что оценка короткого замыкания относится к выражениям IF, CASE и CASE: я бы поспорил, что он также применяется в примере, который вы цитируете, но технически не документирован, что он это делает. Возможно, стоит собрать билет с Oracle по этому поведению, чтобы подтвердить его.

0

Он оценивает операторы OR слева направо и операторы AND справа налево. Я не располагал документацией об этом.

0

Что именно вы подразумеваете под словами «.. и AND справа налево»?
это из документации оракула =>

В следующем примере обратите внимание, что, когда действительные имеет значение FALSE, то все выражение дает FALSE независимо от значения сделано:

действует и сделано

вы можете проверить порядок в следующем примере:

DECLARE
b1 BOOLEAN;
b2 BOOLEAN;

ФУНКЦИЯ CheckIt (v НОМЕР)
RETURN BOOLEAN
IS
НАЧАТЬ
DBMS_OUTPUT.put_line ('внутри checkit:' || v);
RETURN TRUE;
КОНЕЦ checkit;

ПРОЦЕДУРА OUTP (п VARCHAR2, р булево)
IS
НАЧАТЬ
если р
ТОГДА
DBMS_OUTPUT.PUT_LINE (п || 'истинно');
ELSE
DBMS_OUTPUT.put_line (n || 'is false');
END IF;
END;
BEGIN
b1: = checkit (1) И checkit (2);
outp ('b1', b1);
b2: = checkit (3) И checkit (4);
outp ('b2', b2);
END;


внутри CheckIt: 1
внутри CheckIt: 2
b1 верно
внутри CheckIt: 3
внутри CheckIt: 4
б2 истинно