Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
Дано:
drop table test_int_tab 
/
-- Историческая таблица 
create table test_int_tab 
( id integer not null,       -- ID историзируемого объекта 
  start_date date not null,  -- Дата начала действия записи (первая дата, когда запись действует)
  end_date date not null,    -- Дата конца действия записи (последняя дата, когда запись действует)
  val varchar2(50),          -- Некоторое значение
  unique (id, start_date), 
  check (start_date = trunc(start_date)), 
  check (end_date = trunc(end_date)), 
  check (start_date between date '1900-01-01' and date '9999-12-31'), 
  check (end_date between date '1900-01-01' and date '9999-12-31'), 
  check (start_date <= end_date) 
)
/
create or replace procedure set_values 
-- Устанавливает заданное значение на заданном интервале. По окончании работы процедуры 
-- состояние объекта (в данном случае это одно значение) на заданном интервале становится 
-- таким, как задано в параметрах (в данном случае это один параметр p_val) независимо от 
-- истории состояния этого объекта до запуска процедуры (даже если заданном интервале или 
-- части этого интервала объект не существовал). 
( p_id         in integer, -- ID историзируемого объекта 
  p_start_date in date,    -- 
  p_end_date   in date, 
  p_val        in varchar2 
) is 
begin
  null;
end;
/
show errors
Вопрос. Как реализовать процедуру?
Готового ответа не ожидаю. Буду рад ссылкам на теоретические основы и рассуждения по этому поводу, существующие подходы.
Заранее спасибо!
6 апр 11, 17:19    [10481092]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Сергей Арсеньев
Member

Откуда:
Сообщений: 4118
Царь в голове,

Моя мысль застряла на подходе...

Царь в голове
даже если заданном интервале или
-- части этого интервала объект не существовал

Это решается merge.

А вот если существовал, но не один раз и в разных интервалах и какие то из них выходят за границы заданного в параметрах, что делать?
6 апр 11, 17:28    [10481194]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
zzz_z2
Member

Откуда:
Сообщений: 15
Сергей Арсеньев
Царь в голове,

Моя мысль застряла на подходе...

Царь в голове
даже если заданном интервале или
-- части этого интервала объект не существовал

Это решается merge.

А вот если существовал, но не один раз и в разных интервалах и какие то из них выходят за границы заданного в параметрах, что делать?


Разбивать на два?
6 апр 11, 17:37    [10481281]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
Сергей Арсеньев, zzz_z2,

Физических ограничений в таблице нет, но мы считаем, что интервалы не пересекаются. Если заданный интервал накладывается на уже существующие, то эти интервалы должны быть изменены (например, передвижением их границ) или удалены (если это необходимо). Новый интервал может быть получен добавленим новой записи или изменением существующей.

В общем, существует интервальная история состояния объекта. С такого-то по такое-то число объект такой-то имел такое-то значение отрибута val. После запуска процедуры вся история должна остаться прежней за исключением заданного интервала. На заданном интервале должно быть заданное значение.

Свое решение я сейчас разрабатываю, но оно получается громозким. Поэтому хочу узнать, что уже на эту тему придумано.

Структура таблицы у меня именно такая и менять ее нельзя.
6 апр 11, 19:47    [10482023]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
Вот пример.
Было:
idstart_dateend_dateval
2503 янв 201010 янв 2010Красное
2517 янв 201025 янв 2010Синее

Записали:
p_idp_start_datep_end_datep_val
2507 янв 201012 янв 2010Зеленое

Стало:
idstart_dateend_dateval
2503 янв 201006 янв 2010Красное
2507 янв 201012 янв 2010Зеленое
2517 янв 201025 янв 2010Синее
6 апр 11, 20:05    [10482091]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
stax..
Guest
Царь в голове
Сергей Арсеньев, zzz_z2,

Физических ограничений в таблице нет, но мы считаем, что интервалы не пересекаются. Если заданный интервал накладывается на уже существующие, то эти интервалы должны быть изменены (например, передвижением их границ) или удалены (если это необходимо). Новый интервал может быть получен добавленим новой записи или изменением существующей.

В общем, существует интервальная история состояния объекта. С такого-то по такое-то число объект такой-то имел такое-то значение отрибута val. После запуска процедуры вся история должна остаться прежней за исключением заданного интервала. На заданном интервале должно быть заданное значение.

Свое решение я сейчас разрабатываю, но оно получается громозким. Поэтому хочу узнать, что уже на эту тему придумано.

Структура таблицы у меня именно такая и менять ее нельзя.

а что там громоздкого, кучка проверок
если грубо то
блокируем по ид
1) нет перекрытия- вставляем запись
2) есть перекрывающиеся диапазоны
2а удаляем полность перекрытые
2б изменяем частично перекрытые
2в если надо добавляем запись
снимаем блокировку

.....
stax
6 апр 11, 20:53    [10482320]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
zzz_z2
Member

Откуда:
Сообщений: 15
Царь в голове
Вот пример.
Было:
idstart_dateend_dateval
2503 янв 201010 янв 2010Красное
2517 янв 201025 янв 2010Синее



а что было с 11 января по 16? N/A? почему это не отражается в таблице?
6 апр 11, 21:33    [10482482]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
stax.., спасибо! возможно, все действительно не так уж и сложно.

Блокировка по ИД это жестоко. А если вторая сессия захочет изменить историю так, что это не помешает первой сессии?

Если существующий диапазон (1) выходит за заданный (2) в обе стороны, то на месте (1) должно образоваться (1)-(2)-(1), то есть (1) надо скопировать.
6 апр 11, 21:39    [10482505]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
zzz_z2,

с 11 января по 16 объект не существовал. Такая модель. Например, в бане могут быть женские дни в какой-то интервал дат и мужские дни в другой интервал дат. Но в какой-то интервал дат баня может не работать (санитарная обработка, например).
6 апр 11, 21:43    [10482524]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Злой ветеринар
Guest
Царь в голове, а потом удаление исторических дубликатов из таблицы не нужно (слияние интервалов)? Или достаточно только исполнение требования:

-- Устанавливает заданное значение на заданном интервале. По окончании работы процедуры
-- состояние объекта (в данном случае это одно значение) на заданном интервале становится
-- таким, как задано в параметрах (в данном случае это один параметр p_val) независимо от
-- истории состояния этого объекта до запуска процедуры


Например если уже имеются такие данные

id start_date end_date val
====================================
25 01 янв 2010 10 янв 2010 Красное
25 11 янв 2010 20 янв 2010 Зеленое
25 21 янв 2010 31 янв 2010 Красное

и вызывается процедура с параметрами

(
p_id =>25,
p_start_date=> to_date('11.01.2010','dd.mm.yyyy'), --
p_end_date=>to_date('20.01.2010','dd.mm.yyyy'),
p_val =>'Красное'
)

то после ее отработки получаются три эквивалентные по смыслу записи подряд

id start_date end_date val
====================================
25 01 янв 2010 10 янв 2010 Красное
25 11 янв 2010 20 янв 2010 Красное
25 21 янв 2010 31 янв 2010 Красное

хотя "правильный" интервал был бы

d start_date end_date val
====================================
25 01 янв 2010 31 янв 2010 Красное
7 апр 11, 13:53    [10485588]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Злой ветеринар
Guest
Царь в голове
zzz_z2,

с 11 января по 16 объект не существовал. Такая модель. Например, в бане могут быть женские дни в какой-то интервал дат и мужские дни в другой интервал дат. Но в какой-то интервал дат баня может не работать (санитарная обработка, например).


Это не очень хорошая модель. Возможность отсутствия объекта на интервале путает (и пугает). Никогда не знаешь - то ли изменений не прогрузили в таблицу - то ли их не было, то ли процедура неправильно отработала. Отсутствие записи за период ничего не говорит о причине - о том была ли санитарная обработка в бане, звонок о террористической угрозе и заложенном в женском отделении ВУ, ремонт в бане или отсутствие воды в районе из-за аварии. Имхо. Вам, конечно виднее.
7 апр 11, 14:23    [10485863]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
stax..
Guest
Царь в голове
stax.., спасибо! возможно, все действительно не так уж и сложно.

Блокировка по ИД это жестоко. А если вторая сессия захочет изменить историю так, что это не помешает первой сессии?

Если существующий диапазон (1) выходит за заданный (2) в обе стороны, то на месте (1) должно образоваться (1)-(2)-(1), то есть (1) надо скопировать.

ничего не поделаеш, блокировать надо, рассмотрите случай две сессии вставляют для одного ид перекрывающийся диапазон

в зависимости от частоты использования код можно вылизывать
напр если не часто то я б писал банальные IF ... ELSE IF ... так будет понятно и наглядно для сопровождения

а можна напр forall для удаления,
мона первий/последний диапазон определять с использованием row_number(),
мона неявный курсор for, а мож именно в етой задаче луче явный курсор и тд

вариантов много

.....
stax
7 апр 11, 15:10    [10486247]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
Злой ветеринар
хотя "правильный" интервал был бы
...

Да, это было бы "правильнее", но нам сейчас это не нужно. Пусть будет три записи. Выявление таких "дубликатов" слишком сложно с учетом того, что атрибутов можен быть много.
7 апр 11, 15:14    [10486286]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исторических интервалов  [new]
Царь в голове
Member

Откуда: Москва
Сообщений: 170
Злой ветеринар
Это не очень хорошая модель. Возможность отсутствия объекта на интервале путает (и пугает)...
Модель делал не я и менять мне ее нельзя. Пока что работает корректно. Это не таблица хранилища, это настроечная таблица некоторого приложения. Запрос за 14 января (см. пример выше)
select * from test_int_tab where date '2010-01-14' between start_date and end_date
не вернет ни одной записи. Именно это нам и нужно.
7 апр 11, 15:26    [10486363]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить