Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Помогите с триггером-счетчиком, плиз?!


Автор: Kbl4AH 24.9.2008, 15:56
Позарез нужно сделать такую штучку в Oracle 9, но не знаю как(((
В таблицах есть поле ID. Как сделать, чтобы при вставке строк в таблицу или изменении существующих, значение поля ID вставлялось автоматом, причем, чтобы это было значение, которого нет в таблице.
Например, 1 строка - ID 1, 2 строка - ID 2, 3 строка - ID 3... Потом вторую строку удалили, вставили новую строку и у нее ID 2...
Подскажите, пожалуйста. Желательно, чтоб это можно было сделать в PL/SQL Developer.

Автор: DimW 24.9.2008, 17:04
а можно для начала узнать конечную цель. что сподвигло вас на это?

Автор: Nuzur 24.9.2008, 17:09
Kbl4AH, Вообще то если не учитывать 
Цитата

Потом вторую строку удалили, вставили новую строку и у нее ID 2...

То это самый стандартный триггер на вставку из последовательности нового значения... Я конечно могу Вам такой триггер написать какой Вы просите со всеми замечаниями ( дело то плевое ) но вот проблема в том что ЭТО либо будет грузить сервер БД( перебор существующих значений ) либо ЭТО будет чревато дополнительной таблицей записей которые были удалены.
ИМХО бредятина и то и другое + может привести к неприятным сюрпризам если констрейты "забыть" поднять, короче не советую, да и логика УНИКАЛЬНОСТИ ключевого поля в таком случаи как бы теряется... 

Автор: DimW 24.9.2008, 17:21
Цитата(Nuzur @  24.9.2008,  17:09 Найти цитируемый пост)
Я конечно могу Вам такой триггер написать( дело то плевое )

сомниваюсь я что называя данный механизм "плевым" вы задумались о мутации и о том что несколько пользователей одноврименно редактируют таблицу. 
Nuzur, продемонстрируйте приз, а то мож я от жизни отстал...

Автор: Zloxa 24.9.2008, 17:36
Издержки на  реализацию подобного механизма, в подавляющем (если не сказать в абсолютном) большинстве случаев не оправдывает ценности полученного результата, потому вопрос о целеполагании, заданный DimW, более чем обоснован.

Автор: Nuzur 24.9.2008, 17:56
DimW, Я имел в виду как пример для однопользовательского режима конечно smile
Если речь идет об отдельной таблицы то SELECT FOR UPDATE никто не отменял... и там после завизировать как использованный.

ЗЫ в любом случаи идея граблевая и изменить я это не могу.

Zloxa, Спасибо. Но я и сам знаю что вопрос обоснован smile Просто неясно зачем ЭТО человеку нужно. Поэтому "пытаем" его, а вдруг правда промелькнет...

Автор: Kbl4AH 24.9.2008, 19:26
Я, наверное, неправильно выразился...
Мне нужно, чтобы при вставке новой записи или апдейте существующей (апдейт поля ID), значение присваивалось автоматом. Причем это значение должно удовлетворять требованиям: не должно совпадать с уже существующими ID и должно быть не рамдомным, а следующим по списку и минимальным из возможных (если некоторые ID вследствие удаления строк пропущены)...
То есть: 1-е ID - 1, следующее - 2, следующее - 3. Строка с ID 1 - удалена, тогда следующее ID - 1, следующее - 4.
Это можно сделать так: создать счетчик (sequence) на +1 (начиная с 1), а потом создать триггер на инсерт/апдейт (причем ID не повторяются). Мне друг показывал как-то давно, но я сейчас не могу вспомнить...
Нужно мне это для следующего - в проге используются разные справочники, причем поле ID скрыто от пользователя (оно ему не нужно, он оперирует с содержимым). Есть еще таблицы, которые пользователь инсертит/апдейтит (в таблицах значения некоторых полей - ID из справочников, но видит он не ID, а соответствующее им содержимое). То есть пользователю нужны справочники, но он не оперирует с ID. А при редактировании справочника эти ID должны вставляться автоматом.
В Oracle это реализовать легче, чем в Delphi. На словах - использовать в триггере счетчик... Если так - сложно, то нужен хотя бы триггер, который будет автоматом присваивать следующее по порядку значение полю ID (например, вставил строку - ID 1, вставил 2-ю строку - ID 2, вставил 3-ю строку - ID 3; без учета удаленных значенипй ID)

Автор: DimW 25.9.2008, 09:43
Цитата(Kbl4AH @  24.9.2008,  19:26 Найти цитируемый пост)
Я, наверное, неправильно выразился...

да нет же все именно так вас и поняли, поэтому у всех возник один и тот же вопрос, ЗАЧЕМ???

по поводу уникальности поля:
Код

create sequence for_table_test
/
create table test
(
  id   number not null,
  name varchar2(100)
)
/
alter table test
  add constraint test_id_pk primary key (id)
/
create or replace trigger test_bi
before insert
on test
for each row
begin
  select for_table_test.nextval
    into :new.id
   from dual;  
end;
/
insert into test (name) values ('xxx')
/
insert into test (name) values ('zzz')
/
insert into test (name) values ('yyy')
/
select * from test
/


все остальное неимеет смысла даже обсуждать.

Автор: Zloxa 25.9.2008, 09:54
Цитата(Kbl4AH @  24.9.2008,  15:56 Найти цитируемый пост)
Например, 1 строка - ID 1, 2 строка - ID 2, 3 строка - ID 3... Потом вторую строку удалили, вставили новую строку и у нее ID 2...


Цитата(Kbl4AH @  24.9.2008,  19:26 Найти цитируемый пост)
1-е ID - 1, следующее - 2, следующее - 3. Строка с ID 1 - удалена, тогда следующее ID - 1, следующее - 4.

Это же уже совсем другой кампот:
Код

SQL> create table tst (id number primary key, val number);
 
Table created
SQL> create sequence tst$seq;
 
Sequence created
SQL> create trigger tst$bi  before insert on tst for each row
  2  begin
  3    select Tst$seq.nextval into :new.id from dual;
  4  end;
  5  /
 
Trigger created
SQL> insert into tst (val) select dbms_random.value from all_objects where rownum <=3;
 
3 rows inserted
SQL> select * from tst;
 
        ID        VAL
---------- ----------
         1 0.26718483
         2 0.87768983
         3 0.17452977
SQL> delete from tst where id = 1;
 
1 row deleted
SQL> insert into tst (val) values (null);
 
1 row inserted
SQL> select * from tst;
 
        ID        VAL
---------- ----------
         2 0.87768983
         3 0.17452977
         4 
 
SQL> 

Автор: Kbl4AH 25.9.2008, 10:10
Спасибо.

Автор: LSD 25.9.2008, 11:55
Цитата(DimW @  24.9.2008,  18:21 Найти цитируемый пост)
сомниваюсь я что называя данный механизм "плевым" вы задумались о мутации и о том что несколько пользователей одноврименно редактируют таблицу. 

Блокировка на таблицу и "пусть весь мир подождет" smile

Автор: Zloxa 25.9.2008, 12:09
Цитата(LSD @  25.9.2008,  11:55 Найти цитируемый пост)
Блокировка на таблицу и "пусть весь мир подождет" smile 

Угу, а мутацию обходить стейтмент триггером + pl/sql table и "пусть все импорты отвалятся"

Автор: Petro123 25.9.2008, 15:26
Цитата

 и о том что несколько пользователей одноврименно редактируют таблицу. 

А что разве нельзя id сделать unique или я чего то не догоняю...
А что такое мутация?

Добавлено через 6 минут и 35 секунд
А это наверно типа:
 - пользователь A хочет добавить
 - пользователь B уже добавил но свою транзакцию не зафиксировал, 
 - пользователь A не видит добавленное пользователем B

Автор: Zloxa 25.9.2008, 15:38
Цитата(Petro123 @  25.9.2008,  15:26 Найти цитируемый пост)
А что такое мутация?

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm#sthref1287

Цитата(Petro123 @  25.9.2008,  15:26 Найти цитируемый пост)
А это наверно типа

Нет, эта "типа" называется "изоляция тразнакций" smile 

Автор: Petro123 25.9.2008, 15:59
Цитата

А что такое мутация?

Ясно, а можно в двух словах....

Автор: Zloxa 25.9.2008, 16:12
Цитата(Petro123 @  25.9.2008,  15:59 Найти цитируемый пост)
Ясно, а можно в двух словах.... 

А здесь можно материться? Двумя словами и без мата рассказать о мутации, врядли получится. Сходи по ссылочке, не будь ленным, там все написано.

Автор: LSD 25.9.2008, 16:28
Цитата(Zloxa @ 25.9.2008,  17:12)
А здесь можно материться?

Ну если хочется получить бан, то да smile 

Автор: DimW 26.9.2008, 09:13
Цитата(Petro123 @  25.9.2008,  15:59 Найти цитируемый пост)
Ясно, а можно в двух словах.... 

появление не консистентных данных во время выполнения DML оператора, пользователь А и Б не причем.
по простому: такие данные появляются в промежутке между началом и окончанием выполнения DML оператора.
не нужно путать с началом транзакции и ее окончанием!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)