Utgår från LAST_TRANSACTION_DATE
är ett DATE
kolumn (eller TIMESTAMP
) då är båda versionerna mycket dåliga metoder.
I båda fallen DATE
kolumnen kommer implicit att konverteras till en bokstavlig bokstav baserat på de nuvarande NLS-inställningarna. Det betyder att med olika kunder kommer du att få olika resultat.
När du använder datum bokstaver alltid använd to_date()
med(!) en formatmask eller använd en bokstavlig ANSI-datum. På så sätt jämför du datum med datum inte strängar med strängar. Så för lika jämförelse bör du använda:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Observera att användning av 'MON' fortfarande kan leda till fel med olika NLS-inställningar ('DEC'
kontra 'DEZ'
eller 'MAR'
kontra 'MRZ'
). Det är mycket mindre felbenäget med månadsnummer (och fyrsiffriga årtal):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
eller använda ett ANSI-datum bokstavligt
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Anledningen till att ovanstående fråga med stor sannolikhet inte returnerar någonting är den i Oracle DATE
kolumner inkluderar även tiden. Ovanstående bokstavliga datum innehåller implicit tiden 00:00
. Om tiden i tabellen är annorlunda (t.ex. 19:54
) så är datumen naturligtvis inte lika.
För att komma runt det här problemet har du olika alternativ:
- använd
trunc()
i tabellkolumnen för att "normalisera" tiden till00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
detta kommer dock att förhindra användningen av ett index definierat påLAST_TRANSACTION_DATE
- använd
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')
Prestandaproblemet för den första lösningen kan lösas genom att skapa ett index på trunc(LAST_TRANSACTION_DATE)
som skulle kunna användas av det uttrycket. Men uttrycket LAST_TRANSACTION_DATE = '30-JUL-07'
förhindrar också en indexanvändning eftersom den internt bearbetas som to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Viktiga saker att komma ihåg:
- Lita aldrig, aldrig på implicit datatypkonvertering. Det kommer ge dig problem någon gång. Jämför alltid rätt datatyper
- Oracle
DATE
kolumner innehåller alltid en tid som är en del av jämförelsereglerna.