Forudsat LAST_TRANSACTION_DATE er en DATE kolonne (eller TIMESTAMP ) så er begge versioner meget dårlig praksis.
I begge tilfælde DATE kolonne vil implicit blive konverteret til en bogstavelig karakter baseret på de aktuelle NLS-indstillinger. Det betyder, at du med forskellige kunder får forskellige resultater.
Når du bruger bogstaver for dato altid brug to_date() med(!) en formatmaske eller brug en ANSI-dato. På den måde sammenligner du datoer med datoer og ikke strenge med strenge. Så for den lige sammenligning skal du bruge:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Bemærk, at brug af 'MON' stadig kan føre til fejl med forskellige NLS-indstillinger ('DEC' vs. 'DEZ' eller 'MAR' vs. 'MRZ' ). Det er meget mindre fejltilbøjeligt ved at bruge månedstal (og firecifrede årstal):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
eller ved at bruge en ANSI-dato bogstavelig
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Grunden til, at ovenstående forespørgsel med stor sandsynlighed ikke returnerer noget, er den i Oracle DATE kolonner inkluderer også tiden. Ovenstående bogstaver for dato indeholder implicit tiden 00:00 . Hvis tiden i tabellen er anderledes (f.eks. 19:54 ) så er datoerne selvfølgelig ikke ens.
For at løse dette problem har du forskellige muligheder:
- brug
trunc()i tabelkolonnen for at "normalisere" tiden til00:00trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30dette vil dog forhindre brugen af et indeks defineret denLAST_TRANSACTION_DATE - brug
betweenLAST_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')
Ydeevneproblemet for den første løsning kunne løses ved at oprette et indeks på trunc(LAST_TRANSACTION_DATE) som kunne bruges af det udtryk. Men udtrykket LAST_TRANSACTION_DATE = '30-JUL-07' forhindrer også indeksbrug, fordi det internt behandles som to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
De vigtige ting at huske:
- Stol aldrig på implicit datatypekonvertering. Det vil give dig problemer på et tidspunkt. Sammenlign altid de korrekte datatyper
- Oracle
DATEkolonner indeholder altid en tid, som er en del af sammenligningsreglerne.