![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
(Oracle) Как правильно написать триггер для автоприсвоения ID [MySQL]
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-27 16:31:00) [81]2 [28] mr.IL © (27.09.05 16:27)
А по твоему проще? И что будет в этой СП (ХП наверное?)? Тот же запрос?
mr.IL (2005-09-27 16:27:00) [82]Народ, а не проще написать СП , в нее передавать значения будущей записи, в ней получать значение генератора, делать инсерт, а из нее получать ид.
ANB (2005-09-27 16:27:00) [83]
> Sergey13 © (27.09.05 16:24) [27]
- если честно - моя его тоже не понимай.
Sergey13 (2005-09-27 16:24:00) [84]2[26] kesha © (27.09.05 16:07)
Если честно - моя твоя не сильно понимай.
kesha (2005-09-27 16:07:00) [85]
> Sergey13 © (27.09.05 15:10) [8]
smotrja dlja 4ego tebe etot ID:
1: esli tol'ko Insert (vstavili i sabili) -> togda NULL
2: esli Insert delaet Function, kotoraja fozvrazhaet ID -> togda sna4ala
.NEXTVAL into xxx, potom Insert s etim xxx
Sergey13 (2005-09-27 15:57:00) [86]2[23] ANB © (27.09.05 15:52)
ИМХО, да. Можно, если хочется сильно, отдельный скрипт наваять на коррекцию сиквенсов по текущим значениям таблиц. Все лучше, чем лишний код в базе годами крутить.
DenK_vrtz (2005-09-27 15:56:00) [87]>ANB © (27.09.05 15:46) [20]
Если вариант Sergey13 © (27.09.05 15:44) [18] не устраивает(и почему он не универсальный?), то создать две последовательности. Первая идет по четным - вставляешь данные ты, вторая идет по нечетным - вставляет данные кто-то другой
ANB (2005-09-27 15:52:00) [88]
> Desdechado © (27.09.05 15:51) [21]
- то есть лучше вернуться к первому варианту ?
Desdechado (2005-09-27 15:51:00) [89]причем тут универсальность, если заполнение таблиц скриптом выполняется единожды?
ANB (2005-09-27 15:51:00) [90]
> Sergey13 © (27.09.05 14:20) [2]
- точно, ошибку выдала. Вот блин.
ANB (2005-09-27 15:46:00) [91]
> Sergey13 © (27.09.05 15:44) [18]
- думал и над этим. Как то неуниверсально получится.
ANB (2005-09-27 15:45:00) [92]Прошу прощения, в этом триггере и правда была синтаксическая ошибка. Вот так он выглядит в реале :
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_Sq.currval
into Cur_Sq
from dual;
while (Cur_Sq < :new.ID) loop
select Gt_Product_Sq.nextval
into Cur_Sq
from dual;
end loop;
end if;
end Gt_Product_pk_Tr;
Sergey13 (2005-09-27 15:44:00) [93]2[16] ANB © (27.09.05 15:38)
Создавай сиквкенсы и тригера после заполнения. Начальное значение для сиквенса бери как Max+1 ИДшника таблицы.
Sergey13 (2005-09-27 15:40:00) [94]2[15] DenK_vrtz © (27.09.05 15:33)
>Или я чего пропустил, или детальные таблицы причем? :)
При том, что они встречаются. И достаточно часто. И в них иногда надо что-то вставлять. 8-)
ANB (2005-09-27 15:38:00) [95]Ой ой. Как много ответов.
1. Отмечал оракл, но так как на форуме бага, то написал еще и в скобках тип БД.
2. Везде на всякий случай и стоит первый вариант (если ручками изнутри табличку править, то очень удобно), но нарвался на проблему : после создания таблиц схемы я скриптом заполняю начальные данные (справочники) и мне удобно писать там константы, а сиквенс при этом не перемотался и когда начинаешь таблицу корректировать ручками (тут уже все равно, ODAC генерит ID или я сам) получаю ошибку дублирования PK.
2-го варианта будет достаточно ?
ЗЫ. Вернуть ID на клиента, если припрет, не проблема через returning.
DenK_vrtz (2005-09-27 15:33:00) [96]>Sergey13 © (27.09.05 15:28) [13]
Или я чего пропустил, или детальные таблицы причем? :)
Desdechado (2005-09-27 15:29:00) [97]2 ANB [0]
первого варианта достаточно, если не будешь мудрить с придумыванием из головы ID для вставки в таблицу
после INSERT можно узнать ID перезапросом по уникальной комбинации полей или используя фичу Оракла:
INSERT .... RETURNING ... INTO ...
Sergey13 (2005-09-27 15:28:00) [98]2[10] DenK_vrtz © (27.09.05 15:20)
Его можно ( вернее нужно) взять оттуда-же, но до вставки. Например, что бы знать что вставлять в поле связи детальной таблицы.
Курдль (2005-09-27 15:27:00) [99]Странное сочетание "oracle + MySQL" :)
Надеюсь, что это очепятка.
А как подключаетесь к ораклу? Если при помощи наиболее оптимальных для Delphi и испытанных в боях компонентов DOA, то им достаточно указать последовательность, связанную с идентификатором и они все сделают сами!
DenK_vrtz (2005-09-27 15:21:00) [100]т.е. не он, а оно! :)