Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пересечение интервалов / 23 сообщений из 23, страница 1 из 1
03.11.2016, 00:53
    #39340415
Baturin Alexey
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Добрый вечер!

не очень разбираюсь в Oracle, хотел узнать мнение профессионалов
Имеется таблица с колонками DATE_BEGIN и DATE_END, необходимо при добавлении записей проверять, чтобы новые записи не пересекались с уже имеющимися по дате.
Вот такой код вроде работает.
Хотелось бы узнать
1. корректен ли он?
2. будет ли он работать, если данные будут добавлять/изменять из нескольких сессий ?
3. где лучше добавлять такого рода проверки - на уровне приложения, на уровне БД или имеются иные варианты ?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
  CREATE TABLE t 
   (	id integer NOT NULL,
	DATE_BEGIN DATE,
	DATE_END DATE,
	PRIMARY KEY (id),
	check (DATE_BEGIN < DATE_END) 
   );


  CREATE OR REPLACE TRIGGER CHK_CONSISTENCY
   after insert or update of id,DATE_BEGIN,DATE_END on t
   declare l_exst integer;
begin  

  select count(*) into l_exst from t t WHERE 
    exists(select 1 from t ti where t.id <> ti.id
    and ( (ti.DATE_BEGIN between t.DATE_BEGIN and t.DATE_END)
      or (ti.DATE_END between t.DATE_BEGIN and t.DATE_END) ) 
    );

  if l_exst > 0 then 
        RAISE_APPLICATION_ERROR( -20001, 'Overlapped !!!' );
   end if; 
end;


ALTER TRIGGER CHK_CONSISTENCY ENABLE;



INSERT INTO t
(
	id,
	DATE_BEGIN,
	DATE_END
)
select 1, to_date('2001-11-01 10:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 11:30:00','YYYY-MM-DD HH24:MI:SS') from dual
union all
select 2, to_date('2001-11-01 15:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 16:30:00','YYYY-MM-DD HH24:MI:SS') from dual
union all
select 3, to_date('2001-11-01 11:45:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 13:15:00','YYYY-MM-DD HH24:MI:SS') from dual;

INSERT INTO t
(
	id,
	DATE_BEGIN,
	DATE_END
)
select 4, to_date('2001-11-01 16:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 17:30:00','YYYY-MM-DD HH24:MI:SS') from dual;



Заранее благодарен за полезную информацию
...
Рейтинг: 0 / 0
03.11.2016, 01:05
    #39340416
Baturin Alexey
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Забыл версию указать, если это критично
Код: plsql
1.
select * from v$version


Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
...
Рейтинг: 0 / 0
03.11.2016, 01:29
    #39340421
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Baturin Alexey2. будет ли он работать, если данные будут добавлять/изменять из нескольких сессий ?Не будет.
На форуме были примеры, как муторно можно реализовать такую целостность декларативно.
...
Рейтинг: 0 / 0
03.11.2016, 13:47
    #39340778
Baturin Alexey
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Тему можно закрывать, благодарю за коммент

для себя сделал вывод, чтобы грамотно реализовать такое,
необходимо закрывать прямой доступ к INSERT INTO t, т.к. доступ не будет синхронизирован
а для добавления/изменения данных в t использовать процедуру и в ней осуществлять синхронизацию доступа к таблице t, например через запрос

select resource_name into l_resource_name
from another_table
where resource_name = p_resource_name
FOR UPDATE;

далее проверять запросом пересечение интервалов уже в таблице t, и уже вызывать исключение или commit транзакции

подробнее написано по этой ссылке https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:42171194352295
...
Рейтинг: 0 / 0
03.11.2016, 14:51
    #39340864
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Baturin AlexeyТему можно закрывать, благодарю за коммент

для себя сделал вывод, чтобы грамотно реализовать такое,
необходимо закрывать прямой доступ к INSERT INTO t, т.к. доступ не будет синхронизирован
а для добавления/изменения данных в t использовать процедуру и в ней осуществлять синхронизацию доступа к таблице t, например через запрос

select resource_name into l_resource_name
from another_table
where resource_name = p_resource_name
FOR UPDATE;

далее проверять запросом пересечение интервалов уже в таблице t, и уже вызывать исключение или commit транзакции

подробнее написано по этой ссылке https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:42171194352295

2787115
...
Рейтинг: 0 / 0
03.11.2016, 14:53
    #39340866
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Baturin AlexeyТему можно закрывать, благодарю за коммент

для себя сделал вывод, чтобы грамотно реализовать такое,
необходимо закрывать прямой доступ к INSERT INTO t, т.к. доступ не будет синхронизирован
а для добавления/изменения данных в t использовать процедуру и в ней осуществлять синхронизацию доступа к таблице t, например через запрос

select resource_name into l_resource_name
from another_table
where resource_name = p_resource_name
FOR UPDATE;

далее проверять запросом пересечение интервалов уже в таблице t, и уже вызывать исключение или commit транзакции

подробнее написано по этой ссылке https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:42171194352295

Похоже ты прочитал Тома по-диагонали. Том предложил это решeние только потому что "вопрошавший" был на Oracle 9i и "отверг" materialized view решeние только потому что оно на 9i не работает. Надеюсь ты не на 9i?

SY.
P.S. Очень часто читая Тома люди берут предложенные им решения без учета того что этому решению 2, 3, 5 а то и 10 лет а Oracle на месте не стоит...
...
Рейтинг: 0 / 0
03.11.2016, 15:23
    #39340900
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Так, для побалoваться:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
DROP TABLE T PURGE
/
DROP TABLE T_EXPANDED PURGE
/
  CREATE TABLE t 
   (	id integer NOT NULL,
	DATE_BEGIN DATE,
	DATE_END DATE,
	PRIMARY KEY (id),
	check (DATE_BEGIN < DATE_END) 
   );
  CREATE TABLE t_expanded 
   (	DATE_TAKEN DATE UNIQUE
   );


  CREATE OR REPLACE TRIGGER CHK_CONSISTENCY
   before insert
       or delete
       or update
          of DATE_BEGIN,
             DATE_END
   on t
   for each row
   begin
       delete  t_expanded
         where date_taken between :old.date_begin and :old.date_end;
       insert
        into t_expanded
          select  :new.date_begin + (level - 1) / 24 / 3600
            from  dual
            connect by :new.date_begin + (level - 1) / 24 / 3600 <= :new.date_end;
end;
/

SQL> INSERT INTO t
  2  (
  3   id,
  4   DATE_BEGIN,
  5   DATE_END
  6  )
  7  select 1, to_date('2001-11-01 10:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 11:30:00','YYYY-MM-DD HH24:MI:SS') from dual
  8  union all
  9  select 2, to_date('2001-11-01 15:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 16:30:00','YYYY-MM-DD HH24:MI:SS') from dual
 10  union all
 11  select 3, to_date('2001-11-01 11:45:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 13:15:00','YYYY-MM-DD HH24:MI:SS') from dual;

3 rows created.

SQL> 
SQL> INSERT INTO t
  2  (
  3   id,
  4   DATE_BEGIN,
  5   DATE_END
  6  )
  7  select 4, to_date('2001-11-01 16:00:00','YYYY-MM-DD HH24:MI:SS'), to_date('2001-11-01 17:30:00','YYYY-MM-DD HH24:MI:SS') from dual;
INSERT INTO t
            *
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C0014001) violated
ORA-06512: at "SCOTT.CHK_CONSISTENCY", line 4
ORA-04088: error during execution of trigger 'SCOTT.CHK_CONSISTENCY'


SQL> 



SY.
...
Рейтинг: 0 / 0
03.11.2016, 15:42
    #39340923
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
SYТак, для побалoваться:
Код: plsql
1.
(level - 1) / 24 / 3600

Не смешно. Больше похоже на скрытую рекламу какой-нибудь экзадаты.
Её, кстати, хватит для timestamp-а?
...
Рейтинг: 0 / 0
03.11.2016, 15:46
    #39340925
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
SY,

в t_expanded ID не надо?

....
stax
...
Рейтинг: 0 / 0
03.11.2016, 16:56
    #39341014
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
ElicНе смешно. Больше похоже на скрытую рекламу какой-нибудь экзадаты.
Её, кстати, хватит для timestamp-а?

А вот тут все зависит от интервала, поэтому и сказал - для баловства. Например если интервал по дням а не по секундам, то вполне рабочий вариант.
Даже по часам если интервал, скажем, между 1900г и 2100г:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
SQL> select (date '2100-01-01' - date '1900-01-01' + 1) * 24 n from dual;

                       N
------------------------
                 1753200

SQL> 



SY.
...
Рейтинг: 0 / 0
03.11.2016, 20:08
    #39341149
Пересечение интервалов
SY,
Пример и правда интересный.
Но в реальности интервалы обычно привязаны к объектам, которых сто тыщ мильонов.
И в такой ситуации этот способ уже не прокатит'.
Вот если бы можно было чистить t_expanded по завершению транзакции, которая писала в таблицу с интервалами.
Есть в оракле какой-нито "триггер" на коммит?
Или что-то еще можно придумать?
Мне бы пригодились. (:
...
Рейтинг: 0 / 0
03.11.2016, 20:15
    #39341151
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не согласенНо в реальности интервалы обычно привязаны к объектам, которых сто тыщ мильонов.В таком случае у тебя есть через что сериализовать проверку - блокировкой проверяемого объекта.
...
Рейтинг: 0 / 0
03.11.2016, 21:10
    #39341196
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не согласенВот если бы можно было чистить t_expanded по завершению транзакции, которая писала в таблицу с интервалами.


Не понял.

Не согласенЕсть в оракле какой-нито "триггер" на коммит?


Есть - через refresh on commit materialized view.

А так, ждать пока Oracle добавит поддержку констрейнтов к temporal validity.

SY.
...
Рейтинг: 0 / 0
04.11.2016, 10:11
    #39341353
Пересечение интервалов
SY,
Данные в таблице t_expanded нужны только в период внесения изменений в интервалы и только по тем объектам, в интервалы которых вносятся изменения.
Как только началась запись в интервалы, даты блокируются в t_expanded.
Транзакция завершилась - блокировки очищены.
...
Рейтинг: 0 / 0
04.11.2016, 12:24
    #39341393
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не понял. Таблица t_expanded обязана хранить все точки всех интервалов объекта из таблицы t. Так-что в триггере придется заполнять t_expanded точками всех ужe существующих интервалов объекта что eсть мутация, не говоря уже о производительности.

SY.
...
Рейтинг: 0 / 0
04.11.2016, 17:12
    #39341516
Пересечение интервалов
SY,

Производительность, несомненно, просядет, но 4К записей на объект на десятилетие терпимо.
Тем более, что изменение данных на глубину больше года обычно заблокировано, то можно и четырьмя сотнями обойтись.
Мутация тоже не сильно пугает. Т.к. первоначальное заполнение нужно сделать только по тем интервалам, которые были закоммичены до старта транзакции.
Меня смущает другое. Возни с аккуратным заполнением t_expanded будет больше, чем с написанием скрипта, ищущим пересечение интервалов, с последующим разруливанием наложений
...
Рейтинг: 0 / 0
04.11.2016, 18:19
    #39341548
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не согласенМутация тоже не сильно пугает. Т.к. первоначальное заполнение нужно сделать только по тем интервалам, которые были закоммичены до старта транзакции.


Ну и как-же ты её обойдешь? Нет, обойти конечно можно через пакет и набор триггеров но тот еще геморрой ну и производительность опять просядет.

SY.
...
Рейтинг: 0 / 0
07.11.2016, 06:45
    #39342323
Пересечение интервалов
SY,

Я считал, что прагма автономус даёт в триггере доступ к данным закоммиченным до старта текущей транзакции, не вызывая мутацию.
...
Рейтинг: 0 / 0
07.11.2016, 15:52
    #39342736
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не согласенЯ считал, что прагма автономус даёт в триггере доступ к данным закоммиченным до старта текущей транзакции, не вызывая мутацию.

И что тебe даст анонимная транзакция кроме потери транзакционности?

SY.
...
Рейтинг: 0 / 0
08.11.2016, 06:46
    #39343064
Пересечение интервалов
SY,

Сначала под прагмой обновлю состояние в t_expanded по ранее закоммиченным интервалам.
Потом без прагмы обновлю состояние t_expanded по текущему dml.
...
Рейтинг: 0 / 0
08.11.2016, 08:57
    #39343111
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
в любом случае, кроме матвью, будет полезно пару раз в день джоб запускать, для проверки корректности интервалов
...
Рейтинг: 0 / 0
08.11.2016, 16:16
    #39343636
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение интервалов
Не согласенСначала под прагмой обновлю состояние в t_expanded по ранее закоммиченным интервалам.
Потом без прагмы обновлю состояние t_expanded по текущему dml.

Ты сам сeбя послушай: "Данные в таблице t_expanded нужны только в период внесения изменений в интервалы и только по тем объектам, в интервалы которых вносятся изменения". Вот и обьяcни как и что ты внесешь в t_expanded и главное как и когда ты удалишь из t_expanded.

SY.
...
Рейтинг: 0 / 0
09.11.2016, 06:37
    #39343976
Пересечение интервалов
SY,
Три ха-ха. Закольцевались.;)
автор ... и главное как и когда удалить ...
С этого-то я и начал. авторвот если бы можно было чистить
19857379
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пересечение интервалов / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]