viernes, 18 de mayo de 2007

PL/SQL haragán

¿Es PL/SQL 'lazy' para las comparaciones?
Es decir, para evaluar (expr_a AND expr_b): si expr_a es falso entonces ¿se evalúa expr_b?
Asimismo en (expr_a OR expr_b): si expr_a es verdadero entonces ¿se evalúa expr_b?

Opción 1 -> consultar la documentación

Opción 2 -> ¡probarlo!

SQL> create table t (a int);
Table created.
SQL> create or replace function fA return boolean is
2 begin
3 insert into t values (1);
4 return (false);
5 end;
6 /

Function created.

SQL> begin
2 if ((1=0) and fA) = true then
3 NULL;
4 end if ;
5 end;
6 /

PL/SQL procedure successfully completed.

SQL> select * from t;

no rows selected

Conclusión: PL/SQL es lazy. No se insertó un 1 en la tabla ya que la función fA nunca se ejecutó.

¿Y en SQL? ¿Son las condiciones 'lazy' en las consultas?


Lo podemos probar con otra función similar:

SQL>
create or replace function fB return number is
2 begin
3 insert into t values (0);
4 return (0);
5 end;
6 /


En SQL no podría ejecutar esta función, ya que realiza una operación DML:

SQL> select * from dual where ((0 = 0) and (fB = 0));

ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "EMP01.FB", line 3


Sin embargo, si cambiamos AND por OR, notamos que la función fB ni siquiera es evaluada:


SQL> select * from dual where ((0 = 0) or (fB = 0));


D
-
X

1 row selected.

Conclusión: SQL también es lazy. Si se hubiera evaluado la segunda expresión, entonces tendría que haber retornado el error ORA-14551.