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

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

Получение значения из триггера по созданию новой записи [D7, IB6.x]


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

Boroda Oleg ©   (2004-02-04 16:15:00) 

Добрый день!

Точно помню, что уже читал когда-то обсасывание этой проблеммы, но вот где - не помню.

Нужно получить ID записи после ее создания. В самой таблице организован метод автоматической генерации новых ключей через генератор. Естественно, имеется тригер, который, надо думать, срабатывает при создании новых записей. Как "увидеть" из-под Дельфи значение параметра ID после добавления новой записи?


Romkin   (2004-02-06 14:52:00) [21]

2Yuvich Почему так строго, или там, или там? У меня практически всегда и там, и там :))


Yuvich   (2004-02-06 14:49:00) [22]

Обращение к генератору надо оставить или в приложении или в тригере, но в тригере - правильнее. Если нельзя получить значение поля после инсерта, то надо получать это значение до инсерта => обращение к генератору надо оставить в приложении.


Romkin   (2004-02-06 14:39:00) [23]

Deniz © (05.02.04 08:37) [17] и HSolo сказали все абсолютно правильно. А триггер остается на случай, если вставка в таблицу будет сделана не из данного приложения. Это просто гарантия, мало ли, может быть, например, другой разработчик будет работать с таблицей или еще что-нибудь...
2Yuvich нет такого, и не надо. Правда, вставлять можно просто
insert into ... (id, data) values (GEN_ID(MyGen,1), ...)


Johnmen   (2004-02-06 14:34:00) [24]

Синтаксис можешь смело посмотреть здесь
Пуск-Программы-InterBase-Documentation-SQL Reference Help
:)))


Yuvich   (2004-02-06 14:29:00) [25]

А есть ли в синтаксисе insert у IB конструкции типа

insert into ... (id, data) values (0, :data) returning id into :id

где :id :data - параметры вставки.
Тогда вставляем только :data. id не знаем поэтому вставляем 0, а после срабатывания всех тригеров получаем :id.


stud   (2004-02-05 09:51:00) [26]

пардон))
тогда на кой этот триггер нужен?
мы получаем значение генератора в приложение. очевидно предполагается, что его-то мы и запишем в таблицу?


HSolo   (2004-02-05 09:46:00) [27]

>stud © (05.02.04 09:23) [19]
> 2 при вставке записи в таблицу сработал тригер и выдал новое значение

С какого перепугу? Если в триггере ясно сказано:

if (NEW.ID_ACCOUNT is NULL) then NEW.ID_ACCOUNT = gen_id(GEN_ACCOUNT,1);

А этот самый ID_ACCOUNT вовсе не NULL, а записано туда то самое значение генератора, к-рое получили перед вставкой


stud   (2004-02-05 09:23:00) [28]


> Триггер НЕ ТРОГАТЬ.
> В приложении, например перед постом или после вставки:

так вроде при таком раскладе получается:
1 получил значение из генератора
2 при вставке записи в таблицу сработал тригер и выдал новое значение. которое и запишется в таблицу.
либо с точностью до наоборот. но в любом случае полченное в приложении значение и записанное в таблицу будут разные.
так что триггер надо убирать


ЮЮ   (2004-02-05 08:50:00) [29]

>Триггер НЕ ТРОГАТЬ.
>И гарантия, что у каждого юзера(пусть даже 10 чел одновременно нажмут кнопку "добавить") будет СВОЙ ID.

Тольго гарантии идут не столько от тригера, сколько от генератора!

Если даже 10 чел одновременно нажмут кнопку "взять новое значение генератора" (как в триггере) каждый получит СВОЁ


Deniz   (2004-02-05 08:37:00) [30]

> Johnmen © & Boroda Oleg
Вы говорите об одном и том же, но в разных понятиях

Триггер НЕ ТРОГАТЬ.
В приложении, например перед постом или после вставки:

if MyIDField.IsNull then MyIDField.AsInteger:=GetNextID;
...
function GetNextID:Integer;
begin
Query1.Active:=False;
Query1.SQL.Text:=
"select gen_id(GEN_ACCOUNT, 1) from rdb$database";
Query1.Open;
Result:=Query1.Fields[0].AsInteger;
Query1.Close;
end;

И гарантия, что у каждого юзера(пусть даже 10 чел одновременно нажмут кнопку "добавить") будет СВОЙ ID.


Boroda Oleg   (2004-02-04 18:09:00) [31]

Ок. Спасибо.
Буду эксперементировать.


Johnmen   (2004-02-04 18:03:00) [32]

Кажется понял твою проблему...

Убери из триггера. Получай в приложении, до вставки...


Boroda Oleg   (2004-02-04 17:57:00) [33]

Да, но эти значения реально имеются в базе.
Меня же интересует вопрос о том, как их реально получить в Дельфе, причем в строгом соответствии с тем что в базе.

При вызове команды DataSet.Insert внутри БД отрабатывается триггер, который напрямую связан с генератором. Поле ID получает текущее значение генератора, после чего инкринируется на 1. Дельфи этого не видит никак. Она не знает, какое значение в данный момент хранится в генераторе.

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


Johnmen   (2004-02-04 17:44:00) [34]

> Но! 2 юзверя уже имеют эти значения, и они равны

Что-то ты не догоняешь...:)
Если вызвали gen_id(GEN_ACCOUNT,1); то значение генератора наростилось и потом получено было. И следующий вызов, не зависимо от юзера, даст следующее значение...


Boroda Oleg   (2004-02-04 17:42:00) [35]

2 Пубертанец
Прошу прощения, что такое провайдеры? И как определить, даже после refresh значение ID? Сотворить SQL запрос с определением максимального значения ID?


Boroda Oleg   (2004-02-04 17:39:00) [36]

Так тот же смысл получается. Программа же не знает, что юзвери у нас занялись соревнованием по нажатию кнопки "create". Она добросовестно отдаст значение генератора, то которое имеет, а потом создаст две записи, у которых значения ID будут различаться ровно на единичку. Но! 2 юзверя уже имеют эти значения, и они равны. К примеру, оба юзверя успели получить значения 255, а база создала 255 и 256 - в таком случае юзвери добросовестно редактируют строку 255, а строка 256 скорее всего сбросится в базе так как не получит Post.


Пубертанец   (2004-02-04 17:36:00) [37]

Если используешь провайдеры, то для соответствующего провайдера в опциях установи poAutoRefresh. Или после Post можешь вызывать DataSet.Refresh - и читай уже из датасета свой ИД.


Johnmen   (2004-02-04 17:30:00) [38]

>получи_генератор;

Так с наращением получи :) gen_id(GEN_ACCOUNT,1);


Boroda Oleg   (2004-02-04 17:23:00) [39]

Б-р-р-р. Что то не понял.

GEN_ID(MyGenerator,1) - вызывается триггером или это что-то из под самой Дельфи?

Тогда, если в дельфе строится приблизительно такой список процедур:
/* создаем новую запись */
получи_генератор;
DataSource.Insert;

И два юзера умудрились одновременно нажать пимпочку "создать"

Юзер1 - получает значение генератора (кстати, пока не знаю, как это сделать)
Юзер2 - получает значение генератора (то же что и Юзер1!!!)
Юзер1 - создает новую запись
Юзер2 - создает новую запись

Получается, что и Юзер1 и Юзер2 имеют одинаковый ID для Дельфи, а в базе они естественно построены правильно, и оба юзера начнут редактировать одну запись.


Johnmen   (2004-02-04 17:15:00) [40]

>Boroda Oleg (04.02.04 17:02)

Не вижу описание недостатка...:)


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

Наверх

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