sql >> Databasteknik >  >> RDS >> Oracle

Lika med (=) mot LIKE för datumdatatyp

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:

  1. använd trunc() i tabellkolumnen för att "normalisera" tiden till 00: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
  2. 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:

  1. Lita aldrig, aldrig på implicit datatypkonvertering. Det kommer ge dig problem någon gång. Jämför alltid rätt datatyper
  2. Oracle DATE kolumner innehåller alltid en tid som är en del av jämförelsereglerna.


  1. Skillnaden mellan sys.parameters, sys.system_parameters och sys.all_parameters i SQL Server

  2. Hur man ökar filstorleken för en datafil i SQL Server (T-SQL)

  3. Fjärranslutningar Mysql Ubuntu

  4. Hur får jag information om datum/tid från en TIMESTAMP-kolumn?