![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как узнать ID только что добавленной записе в InterBase [D6, IB6.x]
YK © (2005-01-31 11:26:00)Уважаемые Мастера!
Подскажите как узнать ID (автоинкрементное через триггер)
толко что созданной записи в InterBase/
В MS-SQL я знаю, а в InterBase нет :(
P.S.
Может подскажите где найти электронный учебник
по SQL в InterBase?
yk (2005-02-01 15:25:00) [1]Спасибо!
Я вас всех люблю!
p.s.
Это мой первый... триггер
msguns (2005-02-01 15:20:00) [2]>yk © (01.02.05 15:14) [25]
Ааааааааааааааффффффффигеееееть !!!
Барышня, КТО ВАС НАУЧИЛ ТАК ПИСАТЬ ТРИГГЕРА ????????
Как говорил классик жанра Соловьев "засстрелиться" !
yk (2005-02-01 15:19:00) [3]ААААААААААААААААААААА!!!!!!!!!!!!!!!!!!!
ПонятноОООООООООО!!!!
if(New.Id)is null
!!!!!!!!!
:))))))
Johnmen (2005-02-01 15:17:00) [4]М-дя... Случай запущенный...
Полное нежелание читать указанные факи и ответы в данной ветке :(
Хотя бы [2].
yk (2005-02-01 15:16:00) [5]Ведь триггер должен сработать!
yk (2005-02-01 15:14:00) [6]Да всё ведь банально!
Непойму в чем дело 8-(
Вот ОНО:
CREATE TRIGGER "CREATE_ID_CLIENT" FOR "Client"
ACTIVE BEFORE INSERT POSITION 0
AS BEGIN
New."ID_Client" = GEN_ID(ID_Client_gen, 1);
END
CREATE TRIGGER "CREATE_ID_CLIENT_ADDRESS" FOR "Client_Address"
ACTIVE BEFORE INSERT POSITION 0
AS BEGIN
New."ID_Client_Address" = GEN_ID(ID_Client_Address_gen, 1);
END
create procedure INSERT_ALL_FOR_CLIENT
(SurnameCUR char(20) ,NameCUR char(20),
CountryCUR char(20) )
as
declare variable ID_Adr integer;
begin
select GEN_ID(ID_CLIENT_ADDRESS_gen,1) from rdb$database
into :ID_Adr;
insert into "Client_Address"("ID_Client_Address","Country")
values(:ID_Adr,:CountryCUR);
insert into "Client"("Surname","Name","ID_CLIENT_ADDRESS")
values(:SurnameCUR,:NameCUR,:PatronymicCUR,:ID_Adr);
end!!
Johnmen (2005-02-01 15:05:00) [7]А где переменная TAB_1 ?
:)
msguns (2005-02-01 15:05:00) [8]>YK © (01.02.05 15:02) [21]
А ну-ка быстренько текст триггера и полный текст запроса на вставку в студию !!!
;)
msguns (2005-02-01 15:04:00) [9]>Romkin (01.02.05 14:06) [20]
Это ресурс у меня стабильно не работает: говорит, что произошла ошибка сервера. ;(
>И что такое вставить записи "в гриде"? :)
Ну это ж я на известном жаргоне, шоб было понятнее. Имеется в виду, конечно же, редактируемый НД.
Подколка ? ;))
YK (2005-02-01 15:02:00) [10]Переделала на
select GEN_ID(ID_Tab1_gen,1) from rdb$database into :ID_TAB1;
insert into "Tab1"("ID_Tab1",...)
values(:ID_TAB1,...);
несмотря на утверждение Romkin что триггер не
сработае, он сработал! И теперь у меня значение ID_TAB1 в TAB1
на 1 больше чем в
переменной :TAB_1
8-(
Romkin (2005-02-01 14:06:00) [11]msguns © (01.02.05 13:43) [19] http://sql.ru/forum/actualthread.aspx?tid=156051&pg=-1#1288937
И что такое вставить записи "в гриде"? :)
msguns (2005-02-01 13:43:00) [12]>Romkin © (01.02.05 13:10) [16]
Не работаю с IBDataSet и не вставляю записи "в гриде", поэтому, действительно, не обратил внимания на указанный Вами метод класса (точнее, его использование). Может, "в гриде" я и имею возможность получить новое значение генератора, запрошенное самим классом, и т.о. позиционировать датасет на новый рекорд. Однако я предпочитаю "не доверять" такие вещи кому-то, а прописывать их явно. Возможно, я и неправ, но это уже явный офтоп.
По поводу же сабжа - Johnmen © абсолютно верно отметил главное: непонимание автором принципа действия основных механизмов СУБД: триггеров, генераторов, транзакций и т.д.
На ibase.ru до неприличия обширный материал по этому поводу, однако суток автору оказалось недостаточно, чтобы просто туда заглянуть.
Johnmen (2005-02-01 13:13:00) [13]см. http://www.delphimaster.ru/cgi-bin/forum.pl?n=1&id=1107230737&p=2
пост [21]
Romkin (2005-02-01 13:11:00) [14]yk © (01.02.05 13:08) [15] Закон подлости сработает уже при двух пользователях. И ты долго будешь искать глюк...
Romkin (2005-02-01 13:10:00) [15]msguns © (01.02.05 10:40) [12] ДАет :) Ты не дочитал. В датасете на OnNewRecord выполнить запрос select GEN_ID(T_ID_GEN,1) from rdb$database и полученное значение вставить в нужное поле. Оно и будет новым значением. А триггер не сработает.
А вот GEN_ID(T_ID_GEN,0) - нееет! Триггер работает вне контекста транзакции. И никто и никогда не гарантирует, что другая транзакция не изменила его значение :)))
yk (2005-02-01 13:08:00) [16]>HSolo
Значение генератора у меня увеличивается в триггере
before insert
Т.е. я записываю в одну таблицу,
затем хочу(в тй же транзакции)
взять GEN_ID(T_GEN,0)
Почему должен кто-то вклиниться?
msguns (2005-02-01 11:39:00) [17]>Desdechado © (01.02.05 10:50) [13]
>"Триггер отработает вхолостую" только в том случае, если он ничего другого, кроме заполнения первичного ключа, не делает. А вот если что-то еще делает, то совсем даже не вхолостую.
Я говорил не о триггере вообще, а о том, что привел Romkin в [2]. Именно эта моя реплика и вызвала у Вас интерес пополемизировать ([7]).
Считаю вопрос исчерпанным. С уважением.
Desdechado (2005-02-01 10:50:00) [18]2 msguns
Полемизировать нет смысла, мы об одном и том же разными словами говорим.
"Триггер отработает вхолостую" только в том случае, если он ничего другого, кроме заполнения первичного ключа, не делает. А вот если что-то еще делает, то совсем даже не вхолостую.
msguns (2005-02-01 10:40:00) [19]>Desdechado © (31.01.05 16:55) [7]
>почему ж не дает, очень даже дает.
Нет. Не дает. Определение нового ИД в триггере "ДО ВСТАВКИ" позволяет при добавлении новой записи автоматически присвоить ее ид-ру (связанному с соотв.генератором) гарантированно уникальное значение, при условии, что оно не задано явно.
Но триггер ничего не возвращает ! Поэтому клиент не узнает, с каким же все-таки ИД новая запись была добавлена в таблицу.
Такой механизм приемлим, когда клиенту сразу не нужна только что добаленная запись. А если ему запись нужна СРАЗУ ? Например, при отображении датасета после вставки новой записи надо делать ее текущей. В этом случае триггер нам не поможет и надо ручками "дернуть" (под этим словом понимается увеличение счетчика и получение на клиенте нового значения) генератор, полученное значение вставить в запрос и выполнить его. В этом случае триггер отработает "вхолостую", но именно это нас и устроит. После коммита (обязательно, если чтение и запись в разных транзакциях, что классически является правильным для отображаемых датасетов) и переоткрытия НД у нас "на руках" заранее полученный ID новой записи и мы "с легким сердцем" просто
перемещаем указатель НД в содержащую этот ID запись
TDataSet.Locate(Fields[0].FieldName,ID,[])
Кстати, своим следующим предложением Вы подтверждаете мои слова. Зачем же эта фраза ?
ЗЫ. Подробное объяснение, естественно, не для Вас, а для YK ©
Deniz (2005-02-01 09:44:00) [20]http://www.sql.ru/forum/actualthread.aspx?tid=156051