Ervan uitgaande dat LAST_TRANSACTION_DATE is een DATE kolom (of TIMESTAMP ) dan zijn beide versies een zeer slechte gewoonte.
In beide gevallen de DATE kolom wordt impliciet geconverteerd naar een letterlijke letter op basis van de huidige NLS-instellingen. Dat betekent dat je met verschillende klanten verschillende resultaten krijgt.
Bij gebruik van letterlijke datums altijd gebruik to_date() met(!) een formaatmasker of gebruik een letterlijke ANSI-datum. Op die manier vergelijk je datums met datums en niet strings met strings. Dus voor de gelijke vergelijking moet je gebruiken:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Merk op dat het gebruik van 'MON' nog steeds kan leiden tot fouten met verschillende NLS-instellingen ('DEC' vs. 'DEZ' of 'MAR' vs. 'MRZ' ). Het is veel minder foutgevoelig bij het gebruik van maandnummers (en viercijferige jaren):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
of een ANSI-datum letterlijk gebruiken
LAST_TRANSACTION_DATE = DATE '2007-07-30'
De reden waarom de bovenstaande query zeer waarschijnlijk niets zal opleveren, is dat in Oracle DATE kolommen bevatten ook de tijd. De bovenstaande letterlijke datums bevatten impliciet de tijd 00:00 . Als de tijd in de tabel anders is (bijv. 19:54 ) dan zijn de data natuurlijk niet gelijk.
Om dit probleem te omzeilen heeft u verschillende opties:
- gebruik
trunc()in de tabelkolom om de tijd te "normaliseren" naar00:00trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30dit voorkomt echter het gebruik van een index gedefinieerd opLAST_TRANSACTION_DATE - gebruik
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')
Het prestatieprobleem van de eerste oplossing kan worden omzeild door een index te maken op trunc(LAST_TRANSACTION_DATE) die door die uitdrukking zou kunnen worden gebruikt. Maar de uitdrukking LAST_TRANSACTION_DATE = '30-JUL-07' voorkomt ook een indexgebruik omdat het intern wordt verwerkt als to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
De belangrijke dingen om te onthouden:
- Vertrouw nooit op impliciete conversie van gegevenstypes. Het zal op een gegeven moment problemen geven. Vergelijk altijd de juiste gegevenstypen
- Oracle
DATEkolommen bevatten altijd een tijd die deel uitmaakt van de vergelijkingsregels.