Первая ситуация - проверка перекрытия и вывод ошибки
Исходные данные: таблица some_table с ключевым полем key_field и датой действия периода (поля date_from и date_till)
Требования: при вставке записи в таблицу проверять пересечение нового периода с уже существующими в таблице, и в случае перекрытия выводить ошибку.
Реализация: создается триггер на таблицу
Вторая ситуация - сдвиг времени действия старых периодов и вставка нового периода
Исходные данные: таблица some_table с ключевым полем key_field и датой действия периода (поля date_from и date_till)
Требования: при вставке записи в таблицу проверять пересечение нового периода с уже существующими в таблице.
Если пересечения нет - вставляем запись.
Если пересечение есть - сдвигаем даты "от" и "до" старых периодов на 1 секунду, и вставляем запись. Если новый период полностью перекрывает старых - удаляем старую запись.
Реализация:
Исходные данные: таблица some_table с ключевым полем key_field и датой действия периода (поля date_from и date_till)
Требования: при вставке записи в таблицу проверять пересечение нового периода с уже существующими в таблице, и в случае перекрытия выводить ошибку.
Реализация: создается триггер на таблицу
CREATE OR REPLACE TRIGGER some_table_aiu_trg AFTER INSERT OR UPDATE ON some_table REFERENCING NEW AS NEW OLD AS OLD DECLARE l_dummy varchar2(1); CURSOR c_overlap IS SELECT 'x' FROM some_table t1, some_table t2 WHERE t1.key_field = t2.key_field AND t1.date_from <= t2.date_till AND t1.date_till >= t2.date_from AND t1.date_till <> t2.date_till; BEGIN -- Проверяем, нет ли перекрытия OPEN c_overlap; FETCH c_overlap INTO l_dummy; IF c_overlap%found THEN CLOSE c_overlap; raise_application_error(-20050,'Period overlap another period'); END IF; CLOSE c_overlap; END; /
Вторая ситуация - сдвиг времени действия старых периодов и вставка нового периода
Исходные данные: таблица some_table с ключевым полем key_field и датой действия периода (поля date_from и date_till)
Требования: при вставке записи в таблицу проверять пересечение нового периода с уже существующими в таблице.
Если пересечения нет - вставляем запись.
Если пересечение есть - сдвигаем даты "от" и "до" старых периодов на 1 секунду, и вставляем запись. Если новый период полностью перекрывает старых - удаляем старую запись.
Реализация:
DECLARE l_date_from date := to_date('10.07.2013','dd.mm.yyyy'); l_date_till date := to_date('22.07.2013','dd.mm.yyyy'); l_key_field number(5) := 1; BEGIN -- сдвиг предыдущих периодов DELETE FROM some_table t WHERE t.key_field = l_key_field AND t.date_from >= l_date_from AND t.date_till <= l_date_till; UPDATE some_table t SET t.date_till = l_date_from - 1/(24*60*60) WHERE t.key_field = l_key_field AND t.date_from < l_date_from AND t.date_till >= l_date_from; UPDATE some_table t SET t.date_from = l_date_till + 1/(24*60*60) WHERE t.key_field = l_key_field AND t.date_from > l_date_from AND t.date_from < l_date_till AND t.date_till >= l_date_till; -- вставка новой записи INSERT INTO some_table(key_field, date_from, date_till) VALUES (l_key_field, l_date_from, l_date_till); END;
Комментариев нет:
Отправить комментарий