powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Задачка
20 сообщений из 145, страница 6 из 6
Задачка
    #33329327
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И поделом мне. Классический случай который я только-что описал для andrey_anonymous.

SY.
...
Рейтинг: 0 / 0
Задачка
    #33329328
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYИ поделом мне. Классический случай который я только-что описал для andrey_anonymous.

SY.
Бывает.
...
Рейтинг: 0 / 0
Задачка
    #33329664
Stax.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
.....
CREATE OR REPLACE
TRIGGER BIUR_AAA_VIEW
INSTEAD OF INSERT
OR UPDATE
ON AAA_VIEW
FOR EACH ROW
DECLARE
v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM AAA
WHERE LAST_NAME = :NEW.LAST_NAME
AND DEPARTMENT = :NEW.DEPARTMENT;
--
-- а в это время в другой сессии тож вставили две записи :)
--

IF v_cnt >= 3
....
[/src]
SY.
...
Рейтинг: 0 / 0
Задачка
    #33329684
mcureenab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYActually, I overlooked a major issue with your solution. It simply will not work. Assume session A inserts a row (for simplicity lets say table is empty). That row will have index value of 1/#/Q!Q/#/1. Session A does not commit/rollback yet. Now session B tries to insert a row. Obviously, table is locked and session B waits. Now the fun part - read consistency. Since session B transaction started before Session A committed, session B will not see any changes done by session A. So when session A will commit and release the lock, session B will also try to insert index value 1/#/Q!Q/#/1 and will get unique constraint violation.

SY.

"and will get unique constraint violation". Тем не менее ограничение целостности выполняется, хотя в случае конкурентного доступа может возникать ложная тревога. Получив данную ошибку нужно ещё два раза повторить попытку.
...
Рейтинг: 0 / 0
Задачка
    #33329819
mcureenab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__LEV__Да согласен, наверно можно упростить.
По поводу дополнительных таблиц - блокировки (dbms_lock)тоже ведь хранятся в системных таблицах - теже таблицы,та же нагрузка на ввод/вывод.
К тому же количество блокировок ограничено (порядок 10^9), боюсь "на всех не хватит".
Могу ошибаться,но мне кажется, что без дополнительной таблицы (своей, системной и т.п.) не обойтись. Сами посудите: анализировать текущую таблицу в любом типе триггера(пакете и т.п.) - бесполезно - не видно не подтвержденных транзакций других сессий. Хочешь упорядочить операции - юзай оракл (ключи, юник индексы и т.п.). Мне кажется что ответив на этот вопрос(с доп таблицами), мы определимся в каком направлении копать.

Я всегда думал, что пользовательские блокировки размещаются в оперативной памяти, более того, количество одновременно существующих блокировок далеко не 10^9, оно не превышает ENQUEUE_RESOURCES.
При чём надо обратить внимание, что оркл вычисляет ENQUEUE_RESOURCES по умолчанию исходя из того, что пользовательских блокировок не будет. При использовании пользовательских блокировок значение этого параметра нужно увеличивать вручную.

У меня с пользовательскими блокировками был случай. Когда параметры DML_LOCKS и ENQUEUE_RESOURCES оказались несогласованными при выделении большого числа пользовательских блокировок падал фоновый процесс сервера, ему не хватало очередизируемых ресурсов.
...
Рейтинг: 0 / 0
Задачка
    #33330381
mcureenab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё вот такой вариант. Основан на использовании дополнительной таблицы с номерами однофамильцев.
Триггер автоматически назначает свободный номер, который не занят незавершенными транзакциями.
Если все номера заняты, ждёт освобождения одного из них и повторяет попытку.
Если свободных номеров нет совсем, поднимается dup_val_on_index.
Два триггера нужны для того, чтобы правильно отрабатывать ожидание и удаление 0 строк.
Обновление 0 строк работает не совсем корректно, в том плане что ругается на нарушение уникальности,
тогда как обновлять уже нечего.

Код: plaintext
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.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
create table tbl_le3 (
  name varchar2( 30 ),
  ind integer constraint tbl_le3_ind_ck check(ind between  1  and  3 ),
  constraint tbl_le3_pk primary key (ind, name),
  data varchar2( 30 )
);

create table tbl_le3i(
  name varchar2( 30 ),
  ind integer constraint tbl_le3i_ind_ck check(ind between  0  and  3 ),
  constraint tbl_le3i_pk primary key (name, ind)
)
organization index;

create trigger tbl_le3_betg
before insert or update on tbl_le3
for each row
declare
function take_ind(
  new_name varchar2,
  new_ind number
)return number
is
  MAX_NUM constant number :=  3 ;
  res number;
  found boolean;
  busy boolean;
  resource_busy exception;
  pragma exception_init(resource_busy, - 00054 );
  cursor cr1(i number) is
    select ind
    from tbl_le3i
    where name = new_name and i = ind;
  cursor cr2 is
    select ind
    from tbl_le3i
    where name = new_name and  0  < ind;
  cursor cr3(i number) is
    select ind
    from tbl_le3i
    where name = new_name and i = ind for update nowait;
  cursor cr4(i number) is
    select ind
    from tbl_le3i
    where name = new_name and i = ind for update
;
procedure allocate
-- Размещаем в пуле допустимые номера однофамильцев и номер 0,
-- который означает, что пул выделен.
is
  pragma autonomous_transaction;
  name dbms_sql.varchar2_table;
  ind dbms_sql.number_table;
begin
    for i in  0 ..MAX_NUM loop
        name(i) := new_name;
        ind(i) := i;
    end loop;
    forall i in  0 ..MAX_NUM insert into tbl_le3i (name, ind) values (name(i), ind(i));
    commit;
exception
when dup_val_on_index then
    rollback;
end allocate
;
begin
-- Если пул номеров для имени не выделен, выделяем новый пул
    open cr1( 0 ); fetch cr1 into res; found := cr1%found; close cr1;
    if not found then
        allocate;
    end if;
-- Номер назначен явно, просто блокируем запись или сообщаем, что номер занят.
    if new_ind is not null then
        open cr4(new_ind); fetch cr4 into res; found := cr4%found; close cr4;
        if found then
            return new_ind;
        end if;
        raise dup_val_on_index;
    end if;
-- Ищем и блокируем свободный номер в пуле.
    loop
        found := false; -- Свободных номеров нет
        busy := false; -- Заблокированных номеров нет
        for r in cr2 loop
            begin
                open cr3(r.ind); fetch cr3 into res; found := cr3%found; close cr3;
            exception
            when resource_busy then
                busy := true;  -- Нашли заблокированных номер. Запомним...
                res := r.ind;
            end;
            if found then -- Нашли свободный номер.
                return res;
            end if;
        end loop;
        if busy then -- Подождём освобождения номера.
            open cr4(res); fetch cr4 into res; found := cr4%found; close cr4;
            if found then -- Дождались.
                return res;
            end if; -- Номер занят окончательно. Повторяем попытку
        else -- Все номера заняты
            raise dup_val_on_index;
        end if;
    end loop;
end take_ind
;
begin
    :new.ind := take_ind(:new.name, :new.ind);
-- Удаляем номер из пула
    delete tbl_le3i where name = :new.name and ind = :new.ind;
end;
/
show errors trigger tbl_le3_betg
drop trigger tbl_le3_betg
.

create trigger tbl_le3_aetg
after delete or update on tbl_le3
for each row
begin
-- Возвращаем номер в пул
    insert into tbl_le3i (name, ind) values (:old.name, :old.ind);
end;
/
show errors trigger tbl_le3_aetg
drop trigger tbl_le3_aetg
.

drop table tbl_le3;
drop table tbl_le3i;
...
Рейтинг: 0 / 0
Задачка
    #33333370
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYActually, I overlooked a major issue with your solution. It simply will not work. Assume session A inserts a row (for simplicity lets say table is empty). That row will have index value of 1/#/Q!Q/#/1. Session A does not commit/rollback yet. Now session B tries to insert a row. Obviously, table is locked and session B waits. Now the fun part - read consistency. Since session B transaction started before Session A committed, session B will not see any changes done by session A. So when session A will commit and release the lock, session B will also try to insert index value 1/#/Q!Q/#/1 and will get unique constraint violation.
SY.Описанное Вами поведение имеет место быть, но... Как ни странно, это поведение присуще почти всем приведенным реализациям в той или иной форме, а именно: мы должны каким-либо образом "скоординировать" усилия _всех транзакций, производящих изменения, с точки зрения обеспечения уникальности "троичного" :) ключа. В предложенной реализации FBI я не стал этим заниматься, о чем сразу честно написал.
При этом следует сразу отметить, что если таковая синхронизация технически возможна (в чем я почти не сомневаюсь), то ничто не мешает добавить ее в решение на FBI. НО, повторюсь, эта проблема в той или иной форме присуща _всем приведенным _работающим решениям.
Теперь про "разрушенный" индекс.
Обсуждаемое решение предназначено для обеспечения целостности. Оно изначально не предназначалось для обеспечения _поиска. Поэтому данная критика, хотя и справедлива, не имеет практического значения.
Для DML-операций FBI реализует что-то вроде "стека" индексных ключей, чем и обеспечивает целостность. Я пока не нашел сценария, в котором "порушенные" ROWID помешают выполнению основной задачи.
Попробую резюмировать:
- оно работает
- оно НЕ deterministic, и это надо четко понимать (dbms_output я включил специально дабы можно было понаблюдать за этим забавным процессом)
- оно решает вполне конкретную задачу без претензий на "универсальность"
- оно представляется надежнее "триггерных" решений, поскольку:
как справедливо было отмечено, проверит целостность существующих данных уже при создании индекса.

может либо работать целиком, либо не работать вообще (триггера, например, могут быть отключены по одному и включены обратно с предсказуемыми последствиями в виде сложно проверяемой нарушенной целостности данных)
ВАЖНОЕ ЗАМЕЧАНИЕ : "добавочный" кусок кода - обязательная часть решения.
...
Рейтинг: 0 / 0
Задачка
    #33333498
Stax.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Попробую резюмировать:
- оно работает

Код: plaintext
1.
2.
3.
4.
5.
SQL> delete ane_test;
delete ane_test
       *
ERROR at line  1 :
ORA- 08102 : индексированный ключ не найден, obj#  20873 , dba  21300500  ( 2 )
...
Рейтинг: 0 / 0
Задачка
    #33333738
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax. andrey_anonymous
Попробую резюмировать:
- оно работает

Код: plaintext
1.
2.
3.
4.
5.
SQL> delete ane_test;
delete ane_test
       *
ERROR at line  1 :
ORA- 08102 : индексированный ключ не найден, obj#  20873 , dba  21300500  ( 2 )
Хм... А у меня так не получается, все исправно удаляется...
Можно весь сценарий?
И еще один момент - Вы "патчик" прикрутили? (иначе будут проблемы со сценариями, включающими rebuild индекса) =)
...
Рейтинг: 0 / 0
Задачка
    #33333813
Stax.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous Stax. andrey_anonymous
Попробую резюмировать:
- оно работает

Код: plaintext
1.
2.
3.
4.
5.
SQL> delete ane_test;
delete ane_test
       *
ERROR at line  1 :
ORA- 08102 : индексированный ключ не найден, obj#  20873 , dba  21300500  ( 2 )
Хм... А у меня так не получается, все исправно удаляется...
Можно весь сценарий?
И еще один момент - Вы "патчик" прикрутили? (иначе будут проблемы со сценариями, включающими rebuild индекса) =)
патчык не прыкручивал, токо инсерт и делете,
правда я поле ID добавил в таблицу, мне так удобнее,
счас удалю все и постараюсь поторить,
или мона с
Код: plaintext
1.
2.
3.
4.
Name                            Null?    Type
------------------------------- -------- ----
NOM_OTD                         NOT NULL NUMBER
NAME1                           NOT NULL VARCHAR2( 300 )
ID                                       NUMBER( 38 )
жду ответа?
........
Stax
...
Рейтинг: 0 / 0
Задачка
    #33333889
Stax.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax.жду ответа?

Ладно пересоздал
Код: plaintext
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.
 17 : 15 : 03  SQL> create table ane_test( nom_otd number not null -- номер отдела
 17 : 49 : 09     2                        , name1 varchar2( 300 ) not null -- фамилия
 17 : 49 : 09     3   );
create table ane_test( nom_otd number not null -- номер отдела
             *
ERROR at line  1 :
ORA- 00955 : имя уже задействовано для существующего объекта


 17 : 49 : 11  SQL> drop table ane_test;

Table dropped.

 17 : 49 : 24  SQL> create table ane_test( nom_otd number not null -- номер отдела
 17 : 49 : 29     2                        , name1 varchar2( 300 ) not null -- фамилия
 17 : 49 : 29     3   );

Table created.

 17 : 49 : 31  SQL> create unique index ane_test_f_unq on ane_test (substr(ane_test_p.f(nom_otd,name1), 1 , 2000 ));

Index created.

 17 : 50 : 21  SQL> 
 17 : 50 : 21  SQL> ed
Wrote file afiedt.buf

   1   insert into ane_test select  1 ,'q' from dual union all
   2 * select  1 ,'q' from dual
 17 : 51 : 33  SQL> /
insert into ane_test select  1 ,'q' from dual union all
            *
ERROR at line  1 :
ORA- 04068 : существующее состояние пакетов было сброшено
ORA- 04061 : существующее состояния package body "STAX.ANE_TEST_P" стало неприемлемым


 17 : 51 : 34  SQL> /

 2  rows created.

 17 : 51 : 38  SQL> commit;

Commit complete.

 17 : 53 : 15  SQL> delete ane_test;

 2  rows deleted.

 17 : 54 : 27  SQL> commit;

Commit complete.

 17 : 54 : 39  SQL> 

Вторая сессия
Код: plaintext
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.
   1   insert into ane_test select  1 ,'q' from dual union all
   2 * select  1 ,'q' from dual
 17 : 52 : 57  SQL> /
insert into ane_test select  1 ,'q' from dual union all
            *
ERROR at line  1 :
ORA- 04068 : существующее состояние пакетов было сброшено
ORA- 04061 : существующее состояния package body "STAX.ANE_TEST_P" стало неприемлемым
ORA- 04065 : не выполнено, package body "STAX.ANE_TEST_P" изменено или удалено


 17 : 52 : 59  SQL> /
insert into ane_test select  1 ,'q' from dual union all
*
ERROR at line  1 :
ORA- 00001 : нарушено ограничение уникальности (STAX.ANE_TEST_F_UNQ)


 17 : 53 : 15  SQL> /
insert into ane_test select  1 ,'q' from dual union all
*
ERROR at line  1 :
ORA- 00001 : нарушено ограничение уникальности (STAX.ANE_TEST_F_UNQ)


 17 : 53 : 51  SQL> /

 2  rows created.

 17 : 54 : 39  SQL> commit;

Commit complete.

 17 : 55 : 08  SQL> delete ane_test;
delete ane_test
*
ERROR at line  1 :
ORA- 08102 : индексированный ключ не найден, obj#  20879 , dba  21300500  ( 2 )
 17 : 55 : 17  SQL> 

.......
Stax
...
Рейтинг: 0 / 0
Задачка
    #33333972
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax.жду ответа?
Млин, ну ведь терзали же душу смутные сомнения когда я решал - "взрывать" при переполнении или возвращать дублирующий ключ.
Бага.
Все строки
Код: plaintext
rzt := calc_key(p_nom_otd, p_name1, 1 ); -- DUP_VAL_ON_INDEX
следует заменить, к примеру, на
Код: plaintext
raise_application_error(- 20000 ,'в отделе '||p_nom_otd||' не может быть более трех сотрудников с фамилией '||p_name1);
, иначе в некоторых вариантах сценария
- сессия1: delete все вхождения для заданного nom_otd, Name1
- сессия2: insert с переполнением для nom_otd, Name1 (висит, ждет)
- сессия1: commit
- сессия2: _диагностировано переполнение, но запись вставляется, поскольку "гарантированно дублированный ключ" .../#/1 только что удален.
Индекс порушен.
Но к ROWID это не имеет никакого отношения.

Если при обнаружении переполнении просто рвать - все стастается.
Вариант - иметь технологическую запись и в качестве "дублирующего" возвращать "технологический" ключ.
...
Рейтинг: 0 / 0
Задачка
    #33333989
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot andrey_anonymousЕсли при обнаружении переполнении просто рвать - все стастается.[/quot]
Не срастается :(
Да, приведенный алгоритм организации "стека" ущербен.
1: insert
1: insert
1: commit;
1: delete all
2: insert
1: commit;
2: commit;
тоже приведет к нарушению структуры индекса, поскольку последующий delete будут удалять ключ /#/1, а индексе останется /#/3
:(
...
Рейтинг: 0 / 0
Задачка
    #33334002
Stax.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous[quot andrey_anonymousЕсли при обнаружении переполнении просто рвать - все стастается.
Не срастается :(
[/quot]
во-во я тож пробовал fbi но на мутацию нарвался,
а автономная не видит даже себя
.....
Stax
...
Рейтинг: 0 / 0
Задачка
    #33334016
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax.во-во я тож пробовал fbi но на мутацию нарвался,
а автономная не видит даже себя
.....
StaxЯ этого так не оставлю
Задача ставится так: необходимо обеспечить алгоритм формирования индексных ключей такой, что:
1. ключи различны для трех идентичных вхождений (nom_otd, name1).
2. ключ не должен формироваться для четвертого и последующих идентичных вхождений (nom_otd, name1).
3. ключ должен непротиворечиво вычисляться в операциях удаления и вставки узлов индекса.

Собственно, задача - алгоритмическая.
Цимус только в решении без привлечения "посторонних" табличек.
Нужен дешевый способ проверки существования узла индекса с заданным ключем. Тогда delete сможет "пробовать" предполагаемые к удалению ключи, а insert - отыскивать возможные "дырки" и не давать ложных срабатываний.
Можно было бы посмотреть в сторону indextype, но это неспортивно и не позволит оставить за собой приз
...
Рейтинг: 0 / 0
Задачка
    #34023389
Oldwalkman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подниму-ка... (искал материал по теме truncate vs alter table move вот и наткнулся :) ) Задачка интересная.

Все сказанное ИМХО.

Решение можно найти только тремя путями: (1) +доп таблица, (2) +доп колонка и (3) задействовать AQ.

Что касается третьего, то все более-менее прозрачно, но уж очень хитро.

А вот 1 и 2 -- близнецы, только 2-й путь более корявый.

Итак, способ с доп таблицей.

Код: plaintext
1.
2.
3.
4.
5.
6.
create table LOCK2
(
  OTDEL       number        not null,
  LASTNAME    varchar2( 255 ) not null,
  constraint  PK_LOCK2 primary key (OTD, LASTNAME)
);

Оговариваем особо -- все действия по записи в таблицу делать только через наш пакет: insert, move, rename, delete (вставка работника, перемещение меж отделами, смена фамилии, увольнение). Самый простой алгоритм -- для вставки.

0. savepoint lock_begin
1. Делаем insert в таблицу lock2 номера отдела и фамилии
2. Считаем количество однофамильцев в отделе
2.1. Если уже есть три -- rollback до lock_begin и нафик.
2.2. Иначе вставляем в таблицу полноценную запись
3. выполняем delete from lock2 строки с номером отдела и фамилией.
4. commit

В случае переименования или перемещения -- в lock2 пишем две строки. Лучше за один раз, что бы избежать потенциального deadlock (соседняя сессия, к примеру, синхронно вставляет те же две строки, но в обратном порядке)

Удаление -- ну тут как скажут, либо удаляем просто, либо помечаем как уволенного (к слову, у нас ОК не удаляет, employee_id уже за 50К перевалило)

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

Алгоритм, надеюсь, понятен.
...
Рейтинг: 0 / 0
Задачка
    #34023456
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Затык а том, что корректная проверка условия может быть осуществлена только при коммите.
Два пути решения:
1. Было у Tom Kyte несколько раз, например
тут
Строится MV refresh on commit в котором считается число однофамильцев, а на MV создается check constraint.
2. Было в старом Oracle Magazine. В основной таблице создается дополнительная колонка с числом однофамильцев, поддерживается триггерами. На ней висит deferred constaraint, который при коммите проверяет, чтобы однофамильцев было не больше 3.
...
Рейтинг: 0 / 0
Задачка
    #34026186
Oldwalkman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergei.AgalakovЗатык а том, что корректная проверка условия может быть осуществлена только при коммите.


Сергей, изюминка в том, что в моем способе получается, что с конкретной парой Отдел-Фамилия работает строго один процесс, остальные с такой же парой ждут. Если пара другая -- "мы друг другу не мешаем".

=Максим
...
Рейтинг: 0 / 0
Задачка
    #34026346
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Офф. забавный термин: "стандартные локинги БД"
хочется добавить: лэтчинги, коммитинги, процедуринги
...
Рейтинг: 0 / 0
Задачка
    #34026493
mcureenab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oldwalkman...
Алгоритм, надеюсь, понятен.

Понятен, только условие авторСоздать триггер базы данных не выполнено.
...
Рейтинг: 0 / 0
20 сообщений из 145, страница 6 из 6
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Задачка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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