Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

(Oracle) Как правильно написать триггер для автоприсвоения ID [MySQL]


Страницы:   1 2 3 4 5 6

ANB ©   (2005-09-27 14:12:00) 

Попробовал сделать так :

create or replace trigger GT_Product_PK_TR
 before insert on GT_Product
 for each row
declare
begin
 if :New.ID is null then
  select GT_Product_SQ.Nextval into :New.ID from dual;
 end if;
end GT_Product_PK_TR;

Получил проблему - если ID жестко задавать в инсертах, то сиквенс не мотается и потом лезут ошибки.
Переделал :

create or replace trigger GT_Product_PK_TR
 before insert on GT_Product
 for each row
declare
Cur_SQ number;
begin
 if :New.ID is null then
  select GT_Product_SQ.Nextval into :New.ID from dual;
 else
  select GT_Product_Firm_SQ.Currval into Cur_SQ from dual;
  while (Cur_SQ < :New.ID) loop
   select GT_Product_Firm_SQ.Nextval into Cur_SQ from dual;
  end loop;
 end if;
end GT_Product_PK_TR;

В таком варианте вроде, получше, но все равно можно нарваться на дублирование записей. Можно воткнуть еще проверку на существование уже сгенеренного ID и прокручивать сиквенс до нужного значения, но, во первых, полезут ошибки "таблица мутирует", во вторых это ничего особо не даст, т.к. если я умудрюсь в двух разных сессиях сгенерить один и тот же ID, то про триггер на них никак не поругается, так как записи еще не закоммичены, а проблема вылезет при коммите. Хотя, возможно, я не так понял механизм транзакций.


Sergey13   (2005-09-29 12:46:00) [61]

2 [49] ANB ©   (29.09.05 12:40)
А если какому дураку захочется ввести ИД=максимальному значению сиквенса, или около того?


ANB   (2005-09-29 12:40:00) [62]


> Sergey13 ©   (29.09.05 12:33) [48]
- хм. А таки я попробую. Кстати, таки придется втыкать проверку и в Is null. Может кому всеблится отключить триггер, накидать записей, а потом включить. И сиквенс таки не перемотается. Никто не знает, как не напарываться на мутацию при обращении к этой же таблице в триггерре ?


Sergey13   (2005-09-29 12:33:00) [63]

2ANB ©   (29.09.05 12:25)
Добраться до значения сиквенса ведь можно и через
select * from all_sequences
Может это тебя натолкнет на что полезное?
Хотя я по прежнему считаю, что ты перемудриваешь. 8-)


ANB   (2005-09-29 12:25:00) [64]


> Fay ©   (29.09.05 12:21) [46]
- да нарвался уже. Я же постил. Кстати, в НЕКОТОРЫХ случаях может и не дать, но редко. Как раз в моем случае я на нее сразу нарвался. Попробовал заменить на nextval, но обнаружил уже логическую ошибку : если в клиентском приложении я ручками мотаю сиквенс и присваиваю жестко полученный ID. то триггер проматывает его лишний раз.


Fay   (2005-09-29 12:21:00) [65]

2 ANB ©   (27.09.05 15:45) [19]

Обратите внимание на [2]. Sergey13 совершенно прав:
>> select GT_Product_Firm_SQ.Currval
>> может и ошибку дать, если сессия еще не дергала этот сиквенс.

Могу только добавить, что не "может" дать ошибку, а ДАСТ 8)


ANB   (2005-09-29 11:47:00) [66]


> Тогда это будет не твоя проблема. 8-)
- так не солидно. Мне ж за это денежку заплатят. Сверх зарплаты.


Sergey13   (2005-09-29 11:05:00) [67]

2 [43] ANB ©   (29.09.05 10:39)
> А если встеблится добавить скриптиком чего-нибудь ? Со связками ?

Скриптик писать надо с учетом этого или чистить за собой, как уже советовалось в [25]. Это, ИМХО, разумнее, нежели (повторяюсь опять же) "лишний код в базе годами крутить"

>Могу же я себе позволить работать в MS SQL напрямую с автоинкрементарным полем и при этом ничего не ломается ?

Про это не знаю, не работал.

>Плюс пока приклад пишу я, а вот развивать - вовсе не факт.

Тогда это будет не твоя проблема. 8-)


ANB   (2005-09-29 10:39:00) [68]


> Sergey13 ©   (29.09.05 10:34) [42]

А если встеблится добавить скриптиком чего-нибудь ? Со связками ? Могу же я себе позволить работать в MS SQL напрямую с автоинкрементарным полем и при этом ничего не ломается ? Плюс пока приклад пишу я, а вот развивать - вовсе не факт.


Sergey13   (2005-09-29 10:34:00) [69]

2[41] ANB ©   (29.09.05 10:05)
>- не, под клиентом я подразумевал клиентское приложение.
Я догадался. 8-)
Потому и спросил. Если в прикладе прописана вставка ИД из сиквенса, как в таблице появятся левые (не от туда) значения? Из "Плюсов" и "Девелоперов"? Так тогда надо безопасностью заниматься, а не сиквенсы "выравнивать" .
ИМХО.


ANB   (2005-09-29 10:05:00) [70]


> Sergey13 ©   (29.09.05 09:52) [40]
- не, под клиентом я подразумевал клиентское приложение. Я видел уже несколько решений, но они все не очень универсальны и в каждом есть возможность граблей. Просто сейчас рисую небольшой проектик и на нем хотел бы отработать технологию. Если юзер ручками введет дубль, то, ессно, правильным будет поругаться и послать его.


Sergey13   (2005-09-29 09:52:00) [71]

2[39] ANB ©   (29.09.05 09:15)
А откуда ноги растут у твоей озабоченности? С чего бы вдруг юзер стал вводить левые значения и каким образом? Шаловливыми ручками всегда можно вмешаться и на каждый узерский чих заплат не напишешь. ИМХО.


ANB   (2005-09-29 09:15:00) [72]

Таки не нравиться мне то, что получилось. Получается, клиент должен сам заботится о синхронизации сиквенса и ID таблицы. Может таки при ID is null проверять в цикле, что очередное значение сиквенса не конфликтует с ID ? В одной конторе так и сделано, но вылезает другая грабля - по одной записи нормально вставляются, а при пакетной вставке вылезает мутация таблицы.


mr.il   (2005-09-27 17:06:00) [73]

На счет пакета полностью согласен. У меня был вопрос в принципе, об исключении из клиента информации о правилах вставки.
Отдельно спасибо Sergey13, об этом: B>returnung id into :id я не знал


ANB   (2005-09-27 17:03:00) [74]


> Sergey13 ©   (27.09.05 16:59) [36]
- эт точно. Просто у нас в конторе такой подход.


Sergey13   (2005-09-27 16:59:00) [75]

2[34] ANB ©   (27.09.05 16:52)
> Вообще то обычно процедуры вставки в пакет запихивают.  А заодно и для апдейта.
А я обычновообще ХП для этого не использую. Это дело вкуса и конкретных условий, ИМХО.


ANB   (2005-09-27 16:53:00) [76]

ЗЫ. В моем случае оптимально
> Sergey13 ©   (27.09.05 16:50) [33]

(Так примерно ODAC и делает)


ANB   (2005-09-27 16:52:00) [77]


> mr.il ©   (27.09.05 16:44) [32]

Вообще то обычно процедуры вставки в пакет запихивают. А заодно и для апдейта. Потом конечным пользователям даются права на чтение из таблицы, и на исполнение этих процедур. А в теле процедуры проверяются бизнес правила и права пользователя на изменения таблицы.
Но мне для этой задачи этого не нужно. Так как защита не нужна. Чисто внутренний проект.


Sergey13   (2005-09-27 16:50:00) [78]

2 [32] mr.il ©   (27.09.05 16:44)
И чем это проще чем (абстрактно)
insert into Таблица (ид_поле, имя_поле) values (секвенс.NextVal, имя) returnung id into :id
?


mr.il   (2005-09-27 16:44:00) [79]

Ну да, ХП. Ну абстрактно так:
Процедура (Имя  Строка)
IS (ид  Число)
Тело процедуры
ид = секвенс.NextVal
insert into Таблица (ид_поле, имя_поле)
values (ид, имя)

Прошу простить, пишу абстракно, проверить не на чем.


ANB   (2005-09-27 16:36:00) [80]


> Sergey13 ©   (27.09.05 16:31) [30]
- сделал, как ты подсказал. Вернул триггер к первому варианту, а после вставок выполняю перемотку сиквенсов. Вроде, работает.

ЗЫ. Есть куча вариантов через ХП, присвоение ID прямо в инсерте, но они накладывают ограничения на возможности работы с таблицей и ID. При наличии триггера я могу пользоваться как всеми уже указанными способами, так и лениво инсертить в таблицу без указания ID и все будет работать.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо