![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Получение значения из триггера по созданию новой записи [D7, IB6.x]
Boroda Oleg © (2004-02-04 16:15:00)
Добрый день!
Точно помню, что уже читал когда-то обсасывание этой проблеммы, но вот где - не помню.
Нужно получить ID записи после ее создания. В самой таблице организован метод автоматической генерации новых ключей через генератор. Естественно, имеется тригер, который, надо думать, срабатывает при создании новых записей. Как "увидеть" из-под Дельфи значение параметра ID после добавления новой записи?
Romkin (2004-02-06 16:22:00) [1]
Употребив, кстати, TWebConnection вместо TSocketConnection (просто заменив компонент!), ты легко получишь общение с сервером по HTTP :) Правда, обратных вызовов не будет.
MV (2004-02-06 16:19:00) [2]
Thank"s!
Romkin (2004-02-06 16:17:00) [3]
2MV http://rsdn.ru/summary/929.xmlВсе накопано :) Для инета хороша модель потоков Both, stateless сервер. Можно сказать, получаешь пул коннектов...
MV (2004-02-06 15:25:00) [4]
Romkin © (06.02.04 15:23) [41]
2MV У меня трехзвенка :Р Там естественным образом именно так, можно и под инет настроить. По модему, кстати, весьма прилично работает...
... вот шайтан!
А мне еще копать и копать...
MV (2004-02-06 15:23:00) [5]
А IBX - стандартные?
Ставишь
MyIBDataSet.GeneratorField.Field = "ID"
MyIBDataSet.GeneratorField.Generator = "MySuperGenerator"
MyIBDataSet.GeneratorField.ApplyEvent = gamOnNewRecord
потом - вызываешь
MyIBDataSet.insert,
и вот тебе ДО ПОСТА занчение в
MyIBDataSet.FieldByName("ID").AsInteger
И что тут нестандартного (или стандартного?)
Romkin (2004-02-06 15:23:00) [6]
2MV У меня трехзвенка :Р Там естественным образом именно так, можно и под инет настроить. По модему, кстати, весьма прилично работает...
Yuvich (2004-02-06 15:21:00) [7]
> HSolo
Прошу прощения. Невнимательно читал.
> Romkin
Вы правы.
Johnmen (2004-02-06 15:18:00) [8]
>Yuvich (06.02.04 15:15) [37]
>... NEW.ID_ACCOUNT = gen_id(GEN_ACCOUNT,1);
Про ... уже разжевали :)
MV (2004-02-06 15:16:00) [9]
2MV А у меня все через кеширование, транзакции открываются только на момент выборки или внесения изменений :))
Блин, я как-то не подумал о такой возможности, наверное, удобно по всяким там диал-ап соединениям работать... Сейчас грузят меня - типа даваешь интернет, а какой им интернет, если у меня сплошь и рядом Master/detail/subdetail... на локальную сеть оптимизированы...
HSolo (2004-02-06 15:15:00) [10]
> Yuvich (06.02.04 15:02) [30]
Опять 25 :))
> Представь: в приложении генератор возвращает, к примеру, 200. Далее идет инсерт и срабатывает тригер.
В тригере генератор возвращает уже 200 + 1 = 201. В таблицу пишется 201, а приложение "думает" что 200.
Еще раз. Медленно.
1. Приложение дернуло генератор. Получило 200
2. Приложение отправило на сервер insert, где значение ID выставлено в то самое 200 - а зачем, по-Вашему, приложение его получало?
3. На сервере включился триггер. Код триггера:
if (NEW.ID_ACCOUNT is NULL) then NEW.ID_ACCOUNT = gen_id(GEN_ACCOUNT,1);
Код начинает выполняться. Проверяется значение NEW.ID_ACCOUNT - оно равно 200. Значит, условие (NEW.ID_ACCOUNT is NULL) НЕ выполняется. И никто этот несчастный генератор НЕ дергает. И в таблицу вставится именно 200. Так что приложение будет думать совершенно правильно.
Ну, конечно, если это 200 по дороге марсиане унесут... тогда ой :))
А зачем такой триггер нужен, исчерпывающе объяснил Romkin © (06.02.04 14:39) [24]
Yuvich (2004-02-06 15:15:00) [11]
> Johnmen
Как минимум 201. А разве нет? Ведь в тригере написано
... NEW.ID_ACCOUNT = gen_id(GEN_ACCOUNT,1);
> MV
Я ж говорю СТАНДАРТНЫЕ. Процедуры не должны буть нужны.
Romkin (2004-02-06 15:12:00) [12]
ЛУчше универсально, по старинке :)
MV (2004-02-06 15:10:00) [13]
Ну вы, блин, даете!
Посмотрите документацию:
компоненты IBX, компонент TIBDataSet,
свойства:
GeneratorField.Generator
GeneratorField.ApplyEvent
Romkin (2004-02-06 15:08:00) [14]
2Yuvich Стандартный механизм - перечитать запись. Но этого и не требуется, просто запрашиваешь инкремент заранее, и все. Так же и в Oracle. Только MSSQL до сих пор почему-то держится за identity...
Насчет остального: ты строчку
if (NEW.ID_ACCOUNT is NULL) then NEW.ID_ACCOUNT = gen_id(GEN_ACCOUNT,1);
видел? Если у поля уже есть значение, ничего триггер делать не будет! Так что запишется 200
2MV А у меня все через кеширование, транзакции открываются только на момент выборки или внесения изменений :))
MV (2004-02-06 15:05:00) [15]
Ну почему же!
Юзайте процедуры!
Johnmen (2004-02-06 15:05:00) [16]
>В тригере генератор возвращает уже 200 + 1 = 201. В таблицу пишется 201,
Хм-м-м.. С чего бы ?
Yuvich (2004-02-06 15:02:00) [17]
> Romkin
Представь: в приложении генератор возвращает, к примеру, 200. Далее идет инсерт и срабатывает тригер.
В тригере генератор возвращает уже 200 + 1 = 201. В таблицу пишется 201, а приложение "думает" что 200.
> MV: "Знание нового Id на клиенте хорошо тем, что можно компактный рефреш после инсерт/пост сделать ..."
Совершенно верно.
----
Неужели в IB нет стандартного механизма получения значения обновленных полей?
MV (2004-02-06 15:00:00) [18]
2 Romkin © (06.02.04 14:58) [28]
Тоже ОК, хотя придется юзать кэширование изменений, наверное?
Romkin (2004-02-06 14:58:00) [19]
Знание ID сразу на клиенте в основном хорошо для связки мастер-деталь, не требуется постить на сервер мастера, чтобы узнать id, который в записи детали пихать надо. А потом просто в одной транзакции весть пакет пихаешь на сервер.
Romkin (2004-02-06 14:52:00) [20]
2Yuvich Почему так строго, или там, или там? У меня практически всегда и там, и там :))