2014-10-03 13 views

Odpowiedz

10

Aby wybrać bieżącą datę (dzisiaj) przed północą (w jedną sekundę przed) można użyć jednego z następujących stwierdzeń:

SELECT TRUNC(SYSDATE + 1) - 1/(24*60*60) FROM DUAL 
SELECT TRUNC(SYSDATE + 1) - INTERVAL '1' SECOND FROM DUAL; 

Co robi:

  1. Suma jeden dzień SYSDATE: SYSDATE + 1, teraz jest jutro
  2. Usuń część czasu z datą TRUNC, teraz jest jutro o godzinie 00:00
  3. odejmujemy jeden drugi od daty: - 1/(24*60*60) lub - INTERVAL '1' SECOND FROM DUAL, teraz data jest Dzisiaj o 11:59:59

UWAGA 1: Jeśli chcesz sprawdzić date interwały może chcesz sprawdzić @Allan odpowiedzieć poniżej .

Uwaga 2: Jako alternatywę można użyć tego drugi (co jest łatwiejsze do odczytania):

SELECT TRUNC(SYSDATE) + INTERVAL '23:59:59' HOUR TO SECOND FROM DUAL; 
  1. Usuń część czasu w danym dniu z TRUNC, teraz data jest dziś o godzinie 00:00
  2. Dodaj przedział czasowy od 23:59:59, teraz data jest Dzisiaj o 11:59:59

Uwaga 3: Aby sprawdzić wyniki możesz dodać format:

SELECT TO_CHAR(TRUNC(SYSDATE + 1) - 1/(24*60*60),'yyyy/mm/dd hh24:mi:ss') FROM DUAL 
SELECT TO_CHAR(TRUNC(SYSDATE + 1) - INTERVAL '1' SECOND,'yyyy/mm/dd hh24:mi:ss') FROM DUAL 
SELECT TO_CHAR(TRUNC(SYSDATE) + INTERVAL '23:59:59','yyyy/mm/dd hh24:mi:ss') FROM DUAL 
+1

Dlaczego potrzebujesz wyrażenia, aby uzyskać wartość, która nigdy się nie zmieni - jest stała. Dlaczego nie połączysz "23: 59: 59" lub "23:59:59" do dziś? –

+1

@ Caffé: Jeśli wszystko, co robisz, wyświetla to, to dobrze. Jeśli wykonujesz jakiekolwiek przetwarzanie w dniu, to łączenie czasu wymaga dwóch konwersji, podczas gdy wyrażenie nie wymaga żadnego. – Allan

+0

@ Caffé: Nie jestem pewien, czy łącząc jeden koniec z innym wyrażeniem, czy mógłbyś podać przykład? Dzięki! – gaboroncancio

3

Prawdziwy dwuznaczność jest prawdopodobnie z leap seconds a może letni (ale nie wiem, czy istnieje jakiś przypadek, w którym zmienia się północ lub nie).

W każdym razie, dla zwykłego przypadku, istnieje kilka rozwiązań:

-- all of these will produce a `DATE` result: 
SELECT TRUNC(SYSDATE+1)-1/86400 FROM DUAL; 
SELECT TRUNC(SYSDATE+1) - INTERVAL '1' SECOND FROM DUAL; 
SELECT TRUNC(SYSDATE) + INTERVAL '23:59:59' HOUR TO SECOND FROM DUAL; 

niektóre małe dziwactwa, jeśli użyć znacznika czasu mimo:

  • TRUNC dyskretnie przekonwertować wartość DATE;
  • Dodanie/odjęcie NUMBER do/od spowoduje również utworzenie DATE. Aby uzyskać szczegółowe informacje, patrz Datetime/Interval Arithmetic.
-- those two will produce a `DATE` *too*, not a `TIMESTAMP`: 
SELECT TRUNC(SYSTIMESTAMP) + INTERVAL '23:59:59' HOUR TO SECOND FROM DUAL; 

SELECT TO_TIMESTAMP(TRUNC(SYSTIMESTAMP+1))-1/86400 FROM DUAL; 
+1

Trzecia opcja z pierwszego zestawu jest idealna pod względem czytelności i logicznych perspektyw. To dobrze, że Oracle zapewnia tę funkcję i to smutne, że większość ludzi dokumentujących rozwiązania w tym zakresie nadal korzysta z najdziwniejszych rozwiązań. –

6

Osobiście lubię stosując jedną sekundę przed północą.Między innymi, jeśli używasz timestamp, istnieje możliwość, że wartość, którą porównasz, znajdzie się pomiędzy przerwami (tj. 23: 59: 59.1). Ponieważ tego rodzaju logika jest zwykle używana jako granica dla warunku zasięgu, sugeruję użycie "mniej niż północ", niż "mniej niż jedną sekundę przed północą", jeśli w ogóle jest to możliwe. Składnia tego również się upraszcza. Na przykład, aby uzyskać zakres czasowy, który reprezentuje „dzisiaj”, można zastosować jedną z następujących czynności:

date_value >= trunc(sysdate) and date_value < trunc(sysdate) + 1 
date_value >= trunc(sysdate) and date_value < trunc(sysdate) + interval '1' day 

To trochę bardziej kłopotliwe niż przy użyciu between, ale zapewnia, że ​​nigdy nie mają wartości, które wykraczają poza zakresu, który rozważasz.

+0

+1 Nie było jednoznaczne w pytaniu, czy intencją jest sprawdzanie interwału, ale w tym przypadku będzie to z pewnością dobre podejście. –