У меня есть таблица с диапазоном дат начала, диапазоном дат окончания и несколькими другими дополнительными столбцами. При вводе новой записи я хочу автоматически настроить любые перекрывающиеся диапазоны дат (сжимая их, разделяя их или удаляя их, чтобы учесть новый ввод - см. Алгоритм ниже). Я также хочу убедиться, что никакие перекрывающиеся записи не могут быть случайно вставлены в эту таблицу.
Я использую Oracle и Java для кода своего приложения. Как мне обеспечить предотвращение перекрывающихся диапазонов дат, а также разрешить автоматическую настройку перекрывающихся диапазонов? Должен ли я создать триггер AFTER INSERT с dbms_lock для сериализации доступа, чтобы предотвратить наложение данных. Тогда в Java примените логику для автоматической настройки всего? Или эта часть должна быть в PL / SQL при вызове хранимой процедуры? Это то, что нам нужно для пары других таблиц, поэтому было бы неплохо абстрагироваться.
Если у кого-то уже есть что-то подобное, пожалуйста, поделитесь:)
Я нашел эту ссылку: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:474221407101
Вот пример того, как каждый из 4 перекрывающихся случаев должен обрабатываться для корректировки при вставке:
= Example 1 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(20, 50, 'A')
Gives
(0, 10, 'X')
**(20, 50, 'A')
**(51, 100, 'Z')
(200, 500, 'Y')
= Example 2 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(40, 80, 'A')
Gives
(0, 10, 'X')
**(30, 39, 'Z')
**(40, 80, 'A')
**(81, 100, 'Z')
(200, 500, 'Y')
= Example 3 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(50, 120, 'A')
Gives
(0, 10, 'X')
**(30, 49, 'Z')
**(50, 120, 'A')
(200, 500, 'Y')
= Example 4 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(20, 120, 'A')
Gives
(0, 10, 'X')
**(20, 120, 'A')
(200, 500, 'Y')
Алгоритм выглядит следующим образом:
given range = g; input range = i; output range set = o
if i.start <= g.start
if i.end >= g.end
o_1 = i
else
o_1 = i
o_2 = (i.end + 1, g.end)
else
if i.end >= g.end
o_1 = (g.start, i.start - 1)
o_2 = i
else
o_1 = (g.start, i.start - 1)
o_2 = i
o_3 = (i.end + 1, g.end)