Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Получение данных после SQL INSERT

6
27 октября 2009 года
George
4.1K / / 05.01.2007
Вопрос не специфичный к языкам программирования.
Вот вчера возник такой вопрос. Есть таблица, на ней висит триггер on insert, все, что он делает - это генерирует новый ID для вставленной записи. Так вот нужно в программе этот новоявленный ID узнать. В принципе можно выбрать max(ID), но что-то мне подсказывает, что это быдло способ. Хотелось бы по уму.
Помню, в одной программе делали так - в триггер добавляли строки, благодаря которым после вставки делался селект всех только что вставленных айдишников. Попросту говоря INSERT возвращал набор данных. Так я не знаю, как его получить в программе.
5
27 октября 2009 года
hardcase
4.5K / / 09.08.2005
SqlServer: SCOPE_IDENTITY(), IDENT_CURRENT('MyTable'), @@IDENTITY

Правда, что-то мне подсказывает, что они возвращают автоматически создаваемый идентификатор (identity column). На мой взгляд, генерировать первичный ключ своими руками можно только при использовании GUID-а: создали идентификатор, добавили запись (и не парит).
6
27 октября 2009 года
George
4.1K / / 05.01.2007
да, забыл упомянуть, что в моем случае используется БД Firebird. А ID создается триггером, просто берется последний ID и прибавляется единица.
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
в тригерре:
 
Код:
CREATE trigger models_bi for models
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

в процедуре:
Код:
CREATE PROCEDURE MODELMOD (
    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
6
27 октября 2009 года
George
4.1K / / 05.01.2007
Цитата: kot_
...


да, я так и подумал, что скорее всего придется сделать процедуры для вставки объектов. что ж, ты подтвердил мои, так сказать, мысли. =)
спасиб.

1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Washington
да, я так и подумал, что скорее всего придется сделать процедуры для вставки объектов. что ж, ты подтвердил мои, так сказать, мысли. =)
спасиб.


[quote=kot_]
Никогда не работайте с таблицами напрямую - используйте ХП
[/QUOTE]
по другому делать - создавать себе лишнюю головную боль.

6
27 октября 2009 года
George
4.1K / / 05.01.2007
имеется ввиду изменения данных таблицы? или даже SELECT ты рекомендуешь делать через ХП?
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
select я обычно выполняю через View - связка View+ХП выполняет роль промежуточного слоя между данными и клиентским кодом.
6
27 октября 2009 года
George
4.1K / / 05.01.2007
ну в моем случае получится, что вьюшка будет полностью повторять таблицу. ибо структура БД достаточно проста. и взаимосвязанных таблиц почти нет. да их вообще нет. разве есть в таком случае смысл использовать вьюшки?
(про хп то я уже понял)
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
ну это ж тебе решать - имеет смысл или нет. Я лично всегда использую подобную схему - вне зависимости от сложности БД - единый подход к нейменгу и принципам работы с объектами экономит много времени.
11
27 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
вьюшки и ХП представляю собой некий интерфейс БД, на который ты один раз настраиваешь клиента а потом просто дергаешь информацию, при этом ты можешь в корне изменить структуру БД, без перекомпиляции клиента, при условии что внешний интерфейс (вьюшки и ХП) оставишь в прежнем виде.
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: oxotnik333
при этом ты можешь в корне изменить структуру БД, без перекомпиляции клиента, при условии что внешний интерфейс (вьюшки и ХП) оставишь в прежнем виде.


Ну это больше из области поиска хвилософского каменя :) потому что еще ни разу я не сталкивался со ситуацией, когда меняется БД и не меняется клиент (и никто мне продемонстрировать этого не смог).
Но зато версионность и тому подобные вещи, которые значительно облегчают внесение изменений в БД и клиента, подобная схема позволяет реализовать сравнительно легко и без особых затрат, не требуя при этом дублирования информации и таблиц.

288
27 октября 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: kot_

 
Код:
begin
    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) вернет уже значение второй вставки?

241
27 октября 2009 года
Sanila_san
1.6K / / 07.06.2005
Полностью переделывать БД при том же клиенте не доводилось, а вот частичные переделки были, правда, на уровне отдельных таблиц. Там абстракция при помощи ХП пригодилась. Ещё был такой момент, когда внедряли систему уже на рабочей площадке, и вносить какие-то изменения надо было непосредственно там. То есть у себя изменения отрабатывались и потом на продакшен-сервере внедрялись. А разработка на дотнете, перекомпилировать сборки на сервере невозможно было. Поэтому пользовался открытым кодом в ХП. Вельми удобно.

P.S. Не пинайте за дурацкую систему внедрения, я и сам знаю, что это плохо.:)
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: nikitozz
To kot_, поправь меня, пожалуйста, если я не прав, сто лет уже не работал с Firebird. :)
В этой процедуре при многопользовательской БД не может получиться так, что после выполнения триггера и вставки и до получения result вставку сделает транзакция другого клиента (соотвественно "дернув" триггер) и gen_id(gen_models_id,0) вернет уже значение второй вставки?


естественно - триггеры и генераторы работают ВНЕ КОНТЕКСТА ТРАНЗАКЦИИ!!!
По этому во первых их желательно использовать только на стороне сервера, во вторых - если база изначально используется как многопользовательская - то лучше обходится без триггера и вызывать генератор непосредственно в процедуре - т.е. код будет:

 
Код:
begin
    result = gen_id(gen_models_id,1);
    insert into models values(:result,:item_name,:group_id,:order_id,:prim);
   end
1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
Хотя честно говоря мне ни разу не удалось вызвать подобное - но при достаточно большом количестве пользователей (свыше 10 это точно) и при инетенсивной работе с БД по вставке записей можно на подобные грабли наступить.
241
27 октября 2009 года
Sanila_san
1.6K / / 07.06.2005
А зачем тогда вообще пользоваться триггером?
288
27 октября 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: Sanila_san
А зачем тогда вообще пользоваться триггером?



Ну триггер можно и оставить, если нам достаточно просто добавить запись, не получая ее Id. В этом случае триггер избавит от лишней строчки (получение Id).

1
27 октября 2009 года
kot_
7.3K / / 20.01.2000
Ну а так же триггер удобен на этапе тестирования и отладки запросов, формирования данных.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог