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

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

Как правильно организовать транзакцию на вставку в IB?


Страницы:   1 2

KIR ©   (2002-10-31 01:01:00) 

Народ, ситуация следующая (для примера упростим содержание таблиц): Имеется таблица, содержащая PK по полю ID и, скажем, номер документа. Имеются еще несколькотаблиц в которых определенное количество записей ссылаются на главную таблицу (в таблицах имеется поле, скажем MasterID). Записи туда добавляются автоматически при запуске некой процедуры (некоторые рассчитываются, некоторые беруться из StringGrid"ов). Так вот суть этой процедуры такова: добавить 1 запись в главную таблицу (ID генерится с помощью генератор+транзакция "перед вставкой"), затем заполняются все подчиненные таблицы, в которых в поле MasterID заносится только что сгенеренный ID из главной таблицы?

Вопрос следующий: как грамотно организовывается такая вставка:
1. С помощью ХП и огромной кучи параметров (в общей сложности полей около 30)?
2. С помощью Query ---"---?
3. С помощью StartTransaction-Commit из кода клиента?
4. Еще как-то?

Спасибо!


Johnmen   (2002-11-01 23:12:00) [1]

>Alexandr © (01.11.02 15:26)

По п.1) ты прав, я - тормознул...:-))) Дествительно, это возможное применение. Хотя такие вещи если делаются, то наверняка единично или крайне редко, а в этом случае триггер можно просто отключить.


Johnmen   (2002-11-01 16:09:00) [2]

>Alexandr © (01.11.02 15:26)

Честно говоря, я не совсем понял, как приведенные доводы влияют на применение вышеуказанного IF. Особенно п.2) А судя по 1) так этот IF и приведет к "это конец" :o)))


Alexandr   (2002-11-01 15:26:00) [3]

1) копирование таблиц с сохранением ссылочной целостности.
Скажем, есть справочник, на который ссылаются другие таблицы, и мы хотим создать еще одну такую же таблицу в этой или другой (репликация?) базе данных. Если в исходной таблице есть пропуски в значениях ПК, что совершенно нормально, то значения ПК для одних и тех же записей в этих таблицах будут разными, а это конец.
2) Приложение перед вставкой записи в справочник может "застолбыть себе значение ПК (генератора) сделав
select gen_id (code,1) from rdb$database. А потом зная его, его уже и вставить в таблицу, и зная его после вставки точно знать какую имеено запись вставили. Очень просто и быстро.


ну хотябы это.


Johnmen   (2002-11-01 15:20:00) [4]

>Alexandr © (01.11.02 14:43)
>...а апохого от него ничего нет для первичного ключа.

Согласен, нет плохого, и хорошего тоже, то есть это как гриб свинушка, и пользы нет и вреда никакого...

>Есть несколько причин, когда if сильно облегчит жизнь...

Приведи хотя бы одну. Мне это интересно !
:)


Ops   (2002-11-01 14:50:00) [5]

>Johnmen
В целом согласен.


Alexandr   (2002-11-01 14:43:00) [6]

2Johnmen: Не читая всего флейма, позволю себе не согласиться с последним утверждением. Есть несколько причин, когда if сильно облегчит жизнь, а апохого от него ничего нет для первичного ключа.


Johnmen   (2002-11-01 14:34:00) [7]

>Ops (01.11.02 14:16)
>2) Сделать тригер (на вставку)
> IF (NEW.ID_PRODUCTTYPE IS NULL) THEN> NEW.ID_PRODUCTTYPE = GEN_ID(GEN_PRODUCTTYPE_ID,1);

На тему этого IF уже были обсуждения.
Позвольте привести свое мнение - он НЕ нужен ! Резоны :
Его наличие предполагает, что разрабатываемое приложение вдруг начнет писать, не указывая ID ! Но приложение ваше или нет ? Или вы настолько неуверены в том, что написали ?
Далее. Если вдруг ID будет не NULL, а вполне конкретное непримлемое значение ? И что ? Вы защитились от этого ?
Так что вот.........


Ops   (2002-11-01 14:16:00) [8]

Если ты создавал уникальное поле то должен был
1) Сделать генератор
2) Сделать тригер (на вставку)
IF (NEW.ID_PRODUCTTYPE IS NULL) THEN
NEW.ID_PRODUCTTYPE = GEN_ID(GEN_PRODUCTTYPE_ID,1);

3) СДЕЛАТЬ ХРАНИМУЮ ПРОЦЕДУРУ
ID = GEN_ID(GEN_PRODUCTTYPE_ID, 1);

Использование хран процедуры
DM.IBSP_GenID.ExecProc;
ID := DM.IBSP_GenID.ParamByName("ID");

Но Я думаю ты уже во всем разобрался :-)


Johnmen   (2002-11-01 13:12:00) [9]

>KIR © (01.11.02 13:02)
>То есть в ХП вызвать генератор...

Да.

>...потом полученное значение вернуть через SELECT * FROM ХП...

Зачем так сложно ? Просто компонент StoredProc

>...затем использовать полученное значение внутри транзакции...

Тр-ия здесь непричем...

>внутри которой выполняяется вставка сначала в Мастер а затем в
>подчиненные таблицы?

Да.



KIR   (2002-11-01 13:02:00) [10]

То есть в ХП вызвать генератор, потом полученное значение вернуть через SELECT * FROM ХП, затем использовать полученное значение внутри транзакции, внутри которой выполняяется вставка сначала в Мастер а затем в подчиненные таблицы?


Johnmen   (2002-11-01 12:48:00) [11]

Понятно...
Наиболее корректное решение - сначала получить ID (ХП, запрос), а потом это значение вставить (из триггера убрать).
Это относится к Мастеру, если у него предполагается Детейл.


KIR   (2002-11-01 12:33:00) [12]

Никак не получается - устанавливается триггером.

P.S. Сам щас прочитал - бред. Прошу большого прощения! Конечно в первом сообщении надо было написать "генератор+триггер "перед вставкой".


Johnmen   (2002-11-01 12:28:00) [13]

>KIR © (01.11.02 12:07)

Генерится то он генерится, а как твоим приложением получатся ?
Варианты : 1. Запросом 2. ХП 3. Никак не получается (устанавливается в триггером)


KIR   (2002-11-01 12:07:00) [14]

> Johnmen кусок моего первого сообщения в этой ветке: ... ID генерится с помощью генератор+транзакция "перед вставкой"),...

Вроде, насколько я понимаю смысл работы tFIBTransaction, все должно работать нормально. Единственное, что меня смущает совет Ops по поводу получения ID хранимой процедурой. Надо ли это? Что это длжна быть за процедура? Как из нее получать ID? С помошью Query? Не слишком ли это большое нагромождение одного на другое?


Johnmen   (2002-11-01 11:28:00) [15]

>KIR © (31.10.02 13:59)

Приведенный код совершенно ничего не говорит об уникальности ID в мастере ! Так что приведи, как он формируется у тебя...


KIR   (2002-11-01 11:03:00) [16]

Работать-то работает. У меня!А щас как поставишь на 10 машин и начнется... поэтому я так сильно и интересуюсь


Max Zyuzin   (2002-11-01 09:03:00) [17]

Если у тебя все работает, то правильно :)


KIR   (2002-11-01 02:10:00) [18]

Народ, ау...


KIR   (2002-10-31 13:59:00) [19]

В итоге я сделал так:

procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
TA1.StartTransaction;
try
MasterDS.Append;
MasterDS.Post;
i := MasterDS["ID"];
DetailDS.Append;
DetailDS["MasterID"] := i;
DetailDS.Post;
TA1.Commit;
except
TA1.Rollback;
raise;
end;
end;

Правильно? Или все-таки надо вязаться с ХП?


KIR   (2002-10-31 12:44:00) [20]

>Ops Получи ID - хранимой процедурой. (Чтобы другие незахватили)

А как это правильно сделать?


Страницы:   1 2

Наверх

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