sql >> Database teknologi >  >> RDS >> Oracle

Er lig med (=) vs. LIKE for datodatatype

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:

  1. brug trunc() i tabelkolonnen for at "normalisere" tiden til 00:00 trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 dette vil dog forhindre brugen af ​​et indeks defineret den LAST_TRANSACTION_DATE
  2. brug 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')

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:

  1. Stol aldrig på implicit datatypekonvertering. Det vil give dig problemer på et tidspunkt. Sammenlign altid de korrekte datatyper
  2. Oracle DATE kolonner indeholder altid en tid, som er en del af sammenligningsreglerne.


  1. Sådan afspilles PLAY_SOUND i Oracle Forms

  2. SQL-kommandoer snydeark – Sådan lærer du SQL på 10 minutter

  3. Sådan tilføjer du AM/PM til en tids- eller datotidsværdi i MariaDB

  4. SET DATEFIRST – Indstil den første dag i ugen i SQL Server