Domanda

In una procedura memorizzata (che ha un parametro data denominato 'paramDate') ho una query come questa

select id, name
from customer
where period_aded = to_char(paramDate,'mm/yyyy')

Oracle convertirà paramDate in stringa per ogni riga?

Ero sicuro che Oracle non l'avrebbe fatto, ma mi è stato detto che Oracle lo farà.Infatti ho pensato che se il parametro della funzione fosse vincolo (non avesse un campo né un valore calcolato all'interno della query) il risultato dovrebbe essere sempre lo stesso, ed è per questo che Oracle dovrebbe eseguire questa conversione una sola volta.Poi mi sono reso conto che a volte ho eseguito frasi DML in diverse funzioni e forse questo potrebbe causare la modifica del valore risultante, anche se non cambia per ogni riga.

Ciò dovrebbe significare che dovrei convertire tali valori prima di aggiungerli alla query.

Ad ogni modo, forse le "funzioni note" (integrate) vengono valutate una volta, o anche le mie funzioni lo sarebbero.

Comunque, ancora una volta...

Oracle lo eseguirà to_char una volta o Oracle lo farà per ogni riga?

Grazie per le tue risposte

È stato utile?

Soluzione

Non penso che questo sia generalmente il caso, poiché impedirebbe l'utilizzo di un indice.

Almeno per le funzioni integrate, Oracle dovrebbe essere in grado di capire che potrebbe valutarle solo una volta.(Per le funzioni definite dall'utente, vedere di seguito).

Ecco un caso in cui viene utilizzato un indice (e la funzione non viene valutata per ogni riga):

SQL> select id from tbl_table where id > to_char(sysdate, 'YYYY');

--------------------------------------------------------------------------------
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |             |    35 |   140 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| SYS_C004274 |    35 |   140 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("ID">TO_NUMBER(TO_CHAR(SYSDATE@!,'YYYY')))

Per le funzioni definite dall'utente controlla questo articolo.Menziona due modi per garantire che la tua funzione venga chiamata solo una volta:

  1. A partire da Oracle 10.2, è possibile definire la funzione come DETERMINISTIC.

  2. Nelle versioni precedenti è possibile riformularlo per utilizzare la "caching scalare delle sottoquery":

    Selezionare Conteggio (*) da dipendenti in cui lo stipendio = (seleziona getValue (1) da doppio);

Altri suggerimenti

Osservando gli articoli sulla parola chiave DETERMINISTIC (eccone uno, eccone un altro), è stato introdotto per consentire allo sviluppatore di comunicare a Oracle che la funzione restituirà lo stesso valore per gli stessi parametri di input.Quindi, se vuoi che le tue funzioni vengano chiamate solo una volta, e puoi garantire che restituiranno sempre lo stesso valore per gli stessi parametri di input puoi usare la parola chiave DETERMINISTIC.

Per quanto riguarda le funzioni integrate come to_char, Mi rimetto a coloro che sono più esperti nelle viscere dell'Oracolo per darti indicazioni.

La preoccupazione riguardo a to_char non mi dice nulla.Tuttavia, nel tuo PL/SQL, avresti potuto

create or replace procedure ........
  some_variable varchar2(128);
begin

  some_variable := to_char(paramDate,'mm/yyyy');

  -- and your query could read

  select id, name from customer where period_aded = some_variable;
.
.
.
end;
/

Kt

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top