Если у вас нет веских причин использовать PL/SQL, я бы рекомендовал использовать только простой (Oracle) SQL, который является достаточным для:
- Извлечение час и минуту компоненты временной метки с помощью TO_CHAR
- время перевода единицы в стандартизированный временном интервал с NUMTODSINTERVAL
- выполнить сравнение (мин/макс) между столом полного интервалов
- выполнением арифметического (разность) на определенных интервалах
Например:
WITH
daily_updates AS (--My synthetic 100-record impression of your date table
SELECT level AS entry_number
, SYSDATE + level + DBMS_RANDOM.VALUE/2 AS insertion_timestamp
FROM dual
CONNECT BY level<100),
update_times AS (--Conversion of dates to times-since-midnight
SELECT NUMTODSINTERVAL(TO_CHAR(insertion_timestamp,'MI'),'MINUTE') --Extract minutes from date/time, and convert to time interval
+ NUMTODSINTERVAL(TO_CHAR(insertion_timestamp,'HH24'),'HOUR') --Extract hours from date/time, and convert to time interval
AS tsm --Sum of hour and minute components: TSM (Time Since Midnight)
FROM daily_updates)
SELECT max(tsm)-min(tsm) AS time_range --The part you're looking for
, min(tsm) AS earliest_TSM --In case you're curious
, max(tsm) AS latest_TSM --What the min/max TSMs are
FROM update_times
Если вы действительно есть сердце набор на PL/SQL, однако, вы могли бы петля курсор над всеми записями, делая по существу тот же расчет, но без использования преимуществ оптимизаций, которые движок SQL делает за кулисами. Кроме того, вы должны отслеживать built-in INTERVAL DAY TO SECOND type. У вас должно получиться что-то вроде:
DECLARE
FUNCTION get_time_span(verbose IN VARCHAR2 DEFAULT NULL)
RETURN INTERVAL DAY TO SECOND
IS
CURSOR date_entries
IS SELECT insertion_timestamp
FROM daily_updates; --Your date table here
min_TSM INTERVAL DAY TO SECOND;
max_TSM INTERVAL DAY TO SECOND;
current_TSM INTERVAL DAY TO SECOND;
BEGIN
FOR entry IN date_entries LOOP
current_TSM := NUMTODSINTERVAL(TO_CHAR(entry.insertion_timestamp, 'MI'), 'MINUTE')
+ NUMTODSINTERVAL(TO_CHAR(entry.insertion_timestamp, 'HH24'), 'HOUR');
IF min_TSM IS NULL OR current_TSM < min_TSM THEN
min_TSM := current_TSM;
END IF;
IF max_TSM IS NULL OR current_TSM > max_TSM THEN
max_TSM := current_TSM;
END IF;
END LOOP;
RETURN max_TSM - min_TSM;
END get_time_span;
BEGIN
DBMS_OUTPUT.PUT_LINE('The time span is '||get_time_span());
END;
Почему, по вашему мнению, вам нужна хранимая процедура? –
@a_horse_with_no_name Вы имеете в виду часть MAX/MIN? Это всего лишь псевдокод, чтобы показать, что я хочу получить временной интервал из серии значений времени даты, чьи части даты отличаются. В SQL Server я могу использовать тип данных Time, но он, похоже, не существует в PL/SQL. – tete
PL/SQL предназначен только для хранимых процедур, поэтому я просил об этом. Если вам просто нужен запрос, то есть SQL, а не PL/SQL –