Assumendo LAST_TRANSACTION_DATE
è una DATE
colonna (o TIMESTAMP
) quindi entrambe le versioni sono pessime.
In entrambi i casi il DATE
la colonna verrà convertita in modo implicito in un carattere letterale in base alle impostazioni NLS correnti. Ciò significa che con clienti diversi otterrai risultati diversi.
Quando si utilizzano i valori letterali della data sempre usa to_date()
con (!) una maschera di formato o utilizzare una data letterale ANSI. In questo modo si confrontano le date con le date non le stringhe con le stringhe. Quindi per il confronto uguale dovresti usare:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Tieni presente che l'utilizzo di "MON" può comunque causare errori con impostazioni NLS diverse ('DEC'
rispetto a 'DEZ'
o 'MAR'
rispetto a 'MRZ'
). È molto meno soggetto a errori utilizzando i numeri dei mesi (e gli anni a quattro cifre):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
o utilizzando una data letterale ANSI
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Ora il motivo per cui è molto probabile che la query sopra non restituisca nulla è che in Oracle DATE
le colonne includono anche l'ora. I valori di data sopra riportati contengono implicitamente l'ora 00:00
. Se l'ora nella tabella è diversa (es. 19:54
) quindi ovviamente le date non sono uguali.
Per aggirare questo problema hai diverse opzioni:
- usa
trunc()
nella colonna della tabella per "normalizzare" l'ora a00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
ciò impedirà comunque l'utilizzo di un indice definito ilLAST_TRANSACTION_DATE
- usa
between
LAST_TRANSACTION_DATE between to_date('2007-07-30 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and to_date('2007-07-30 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
Il problema delle prestazioni della prima soluzione potrebbe essere risolto creando un indice su trunc(LAST_TRANSACTION_DATE)
che potrebbe essere utilizzato da tale espressione. Ma l'espressione LAST_TRANSACTION_DATE = '30-JUL-07'
impedisce anche l'utilizzo di un indice perché internamente viene elaborato come to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Le cose importanti da ricordare:
- Mai, mai fare affidamento sulla conversione implicita del tipo di dati. farà darti problemi ad un certo punto. Confronta sempre i tipi di dati corretti
- Oracle
DATE
le colonne contengono sempre un'ora che fa parte delle regole di confronto.