sintaxis funcion ejemplos consultas clausula avanzadas sql oracle plsql sqlplus deterministic

funcion - sintaxis sql server 2008



¿Por qué una función determinista ejecuta un tiempo extra en SQL? (1)

Dada la siguiente tabla

create table tmp_test as select mod(level, 5) as n from dual connect by level <= 10 ;

y esta función

create or replace function test_deterministic (Pn in number ) return number deterministic is begin dbms_output.put_line(Pn); dbms_lock.sleep(1); return Pn; end;

Se ejecuta 6 veces, tomando 6 segundos:

SQL> select test_deterministic(n) from tmp_test; TEST_DETERMINISTIC(N) --------------------- 1 2 3 4 0 1 2 3 4 0 10 rows selected. 1 2 3 4 0 1 Elapsed: 00:00:06.02

Hubiera esperado que esto se ejecutara 5 veces. Si ejecuto esta instrucción SELECT en SQL Developer o PL / SQL Developer, solo se ejecuta 5 veces. Igualmente, si ejecuto esto en Pl / SQL, se ejecuta 5 veces:

SQL> begin 2 for i in ( select test_deterministic(n) from tmp_test ) loop 3 null; 4 end loop; 5 end; 6 / 1 2 3 4 0 Elapsed: 00:00:05.01

¿Por qué se ejecuta esta función 6 veces cuando se llama en SQL desde SQL * Plus? Esperaba que se ejecutara 5 veces.

Estoy en la versión 11.2.0.3.5 y el cliente SQL * Plus es la versión 11.2.0.1.0 (64 bits).


Culpa SQL * Plus, Ben. Su función funciona, en esta situación, correctamente. El valor extra ( 1 ) que ve está allí debido arraysize valor de arraysize y, sobre todo, a la forma en que SQL * Plus obtiene las filas. Primero obtiene la primera fila y solo luego comienza a usar arraysize para arraysize posteriores. Cada nueva búsqueda es una nueva llamada a la base de datos, lo que obliga a evaluar su función determinista. Intente configurar el arraysize en 1 o 2 (mismo efecto) y ejecute su instrucción de select . La primera fila retorna, y luego, entra en juego el arraysize y cada arraysize posterior devolverá dos filas:

Arraysize se establece en 1 (dos de hecho)

SQL> set arraysize 1; SQL> select test_deterministic(n) from tmp_test; TEST_DETERMINISTIC(N) --------------------- 1 2 3 4 0 1 2 3 4 0 10 rows selected. 1 2 3 4 0 1 2 3 4 0 Elapsed: 00:00:10.10

La misma consulta con un arraysize mucho más arraysize :

SQL> set arraysize 50; SQL> select test_deterministic(n) from tmp_test; TEST_DETERMINISTIC(N) --------------------- 1 2 3 4 0 1 2 3 4 0 10 rows selected. 1 2 3 4 0 1 Elapsed: 00:00:06.06 SQL> spool off;

Cualquier otro cliente, ya sea SQL Developer o PL / SQL Developer, carece de dicho comportamiento y proporciona el resultado correcto.