Получение данных после SQL INSERT
Вот вчера возник такой вопрос. Есть таблица, на ней висит триггер on insert, все, что он делает - это генерирует новый ID для вставленной записи. Так вот нужно в программе этот новоявленный ID узнать. В принципе можно выбрать max(ID), но что-то мне подсказывает, что это быдло способ. Хотелось бы по уму.
Помню, в одной программе делали так - в триггер добавляли строки, благодаря которым после вставки делался селект всех только что вставленных айдишников. Попросту говоря INSERT возвращал набор данных. Так я не знаю, как его получить в программе.
Правда, что-то мне подсказывает, что они возвращают автоматически создаваемый идентификатор (identity column). На мой взгляд, генерировать первичный ключ своими руками можно только при использовании GUID-а: создали идентификатор, добавили запись (и не парит).
active before insert position 0
as
begin
if (new.item_id is null or (new.item_id = -1) ) then
new.item_id = gen_id(gen_models_id,1);
end
в процедуре:
item_id integer,
item_name varchar(50),
oper_id integer,
order_id integer,
group_id integer,
prim varchar(150))
returns (
result integer)
as
begin
/* Procedure Text */
if (order_id is null) then
order_id = 0;
if(oper_id = 0) then
begin
insert into models values(:item_id,:item_name,:group_id,:order_id,:prim);
result = gen_id(gen_models_id,0);
end
suspend;
end
да, я так и подумал, что скорее всего придется сделать процедуры для вставки объектов. что ж, ты подтвердил мои, так сказать, мысли. =)
спасиб.
спасиб.
[quote=kot_]
Никогда не работайте с таблицами напрямую - используйте ХП
[/QUOTE]
по другому делать - создавать себе лишнюю головную боль.
(про хп то я уже понял)
Ну это больше из области поиска хвилософского каменя :) потому что еще ни разу я не сталкивался со ситуацией, когда меняется БД и не меняется клиент (и никто мне продемонстрировать этого не смог).
Но зато версионность и тому подобные вещи, которые значительно облегчают внесение изменений в БД и клиента, подобная схема позволяет реализовать сравнительно легко и без особых затрат, не требуя при этом дублирования информации и таблиц.
insert into models values(:item_id,:item_name,:group_id,:order_id,:prim);
result = gen_id(gen_models_id,0);
end
To kot_, поправь меня, пожалуйста, если я не прав, сто лет уже не работал с Firebird. :)
В этой процедуре при многопользовательской БД не может получиться так, что после выполнения триггера и вставки и до получения result вставку сделает транзакция другого клиента (соотвественно "дернув" триггер) и gen_id(gen_models_id,0) вернет уже значение второй вставки?
P.S. Не пинайте за дурацкую систему внедрения, я и сам знаю, что это плохо.:)
В этой процедуре при многопользовательской БД не может получиться так, что после выполнения триггера и вставки и до получения result вставку сделает транзакция другого клиента (соотвественно "дернув" триггер) и gen_id(gen_models_id,0) вернет уже значение второй вставки?
естественно - триггеры и генераторы работают ВНЕ КОНТЕКСТА ТРАНЗАКЦИИ!!!
По этому во первых их желательно использовать только на стороне сервера, во вторых - если база изначально используется как многопользовательская - то лучше обходится без триггера и вызывать генератор непосредственно в процедуре - т.е. код будет:
result = gen_id(gen_models_id,1);
insert into models values(:result,:item_name,:group_id,:order_id,:prim);
end
Ну триггер можно и оставить, если нам достаточно просто добавить запись, не получая ее Id. В этом случае триггер избавит от лишней строчки (получение Id).