Za předpokladu LAST_TRANSACTION_DATE
je DATE
sloupec (nebo TIMESTAMP
), pak jsou obě verze velmi špatným postupem.
V obou případech DATE
sloupec bude implicitně převeden na znakový literál na základě aktuálního nastavení NLS. To znamená, že s různými klienty získáte různé výsledky.
Při použití datových literálů vždy použijte to_date()
s(!) maskou formátu nebo použijte datový literál ANSI. Tímto způsobem porovnáváte data s daty, nikoli řetězce s řetězci. Takže pro rovné srovnání byste měli použít:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Pamatujte, že použití 'MON' může stále vést k chybám s různými nastaveními NLS ('DEC'
vs. 'DEZ'
nebo 'MAR'
vs. 'MRZ'
). Je mnohem méně náchylné k chybám při použití čísel měsíců (a čtyřmístných let):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
nebo pomocí datového literálu ANSI
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Důvodem, proč je velmi pravděpodobné, že výše uvedený dotaz nic nevrátí, je to, že v Oracle DATE
sloupce obsahují také čas. Výše uvedené datové literály implicitně obsahují čas 00:00
. Pokud je čas v tabulce jiný (např. 19:54
), pak se samozřejmě data nerovnají.
Chcete-li tento problém vyřešit, máte různé možnosti:
- použijte
trunc()
ve sloupci tabulky "normalizovat" čas na00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
to však zabrání použití indexu definovaného dneLAST_TRANSACTION_DATE
- použijte
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')
Problém s výkonem prvního řešení by se dal vyřešit vytvořením indexu dne trunc(LAST_TRANSACTION_DATE)
který by mohl být použit tímto výrazem. Ale výraz LAST_TRANSACTION_DATE = '30-JUL-07'
zabraňuje také použití indexu, protože interně je zpracován jako to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Důležité věci k zapamatování:
- Nikdy, nikdy nespoléhejte na implicitní konverzi datových typů. Bude vám v určitém okamžiku způsobí problémy. Vždy porovnávejte správné datové typy
- Oracle
DATE
sloupce vždy obsahují čas, který je součástí porovnávacích pravidel.