Узнать значение ID только, что вставленной записи

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
AkANz
новенький
Сообщения: 26
Зарегистрирован: 16.03.2010 12:59:02
Откуда: Алтайский край

Узнать значение ID только, что вставленной записи

Сообщение AkANz »

Есть необходимость узнать значение автоинкриментного id_hospital_in (первичный ключ) только, что вставленной записи.
В обработчике Click (кнопка Сохранить) - запрос (для примера остальные значения убраны):
zqHospitalInEdit.SQL.Clear;
zqHospitalInEdit.SQL.Add('INSERT INTO hospital_in (id_hospital_in)'VALUES (default) RETURNING id_hospital_in');
fmDM.zqHospitalInEdit.ExecSQL;

Подскажите, пожалуйста, как мне вернуть на форму значение id_hospital_in возвращаемое этим запросом.
alex_rain
новенький
Сообщения: 26
Зарегистрирован: 12.02.2010 05:56:32
Откуда: Russia

Сообщение alex_rain »

Возможно сработает zqHospitalInEdit.Active := True вместо zqHospitalInEdit.ExecSQL.
И далее, например, Label1.Caption := IntToStr(zqHospitalInEdit.Fields[0].AsInteger).

Lazarus 0.9.29 FPC 2.5.1 Win32
AkANz
новенький
Сообщения: 26
Зарегистрирован: 16.03.2010 12:59:02
Откуда: Алтайский край

Сообщение AkANz »

Спасибо, alex_rain.
Так сработало.
krab
постоялец
Сообщения: 108
Зарегистрирован: 17.02.2010 17:23:08

Сообщение krab »

alex_rain писал(а):Возможно сработает zqHospitalInEdit.Active := True вместо zqHospitalInEdit.ExecSQL.
Lazarus 0.9.29 FPC 2.5.1 Win32

есть еще zqHospitalInEdit.Open
Аватара пользователя
grigoreo
постоялец
Сообщения: 195
Зарегистрирован: 10.03.2009 14:43:43
Откуда: С нашей Раши

Сообщение grigoreo »

или запросом получить текущее значение SEQUENCE для этой таблицы если конечно это поле у вас serial
AkANz
новенький
Сообщения: 26
Зарегистрирован: 16.03.2010 12:59:02
Откуда: Алтайский край

Сообщение AkANz »

Помогите, пожалуйста, теперь сделать то-же самое, т.е узнать значение ID только, что вставленной записи, но уже для Firebird.
Имеем (для примера лишнее убрано)
quTemp.SQL.Clear;
quTemp.SQL.Add('INSERT INTO hospital_in (medical_type 'VALUES (:medical_type) RETURNING id_hospital_in ');
quTemp.Open;

Поле id_hospital_in первичный ключ с триггером и генератором (при вставке значение увеличивается на 1)
Для подключения к Firebird используется UIB+FBDataSet (UIB 2.1)

Если этот запрос выполнить в IBExpert, то значение id_hospital_in возвращается, а в Lazarus вываливается ошибка.
Видимо UIB не поддерживает RETURNING.
Каким образом можно еще вернуть ID только, что вставленной записи?
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

Вообще, если с самого начала, то делать надо так:

CREATE SEQUENCE GEN_NEW_TABLE_ID;
ALTER SEQUENCE GEN_NEW_TABLE_ID RESTART WITH 0;


CREATE OR ALTER TRIGGER NEW_TABLE_BI FOR NEW_TABLE
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.id is null) then
new.id = gen_id(gen_new_table_id,1);
end

create trigger new_table_bi for new_table
active before insert position 0
as
begin
if (new.new_field is null) then
new.new_field = gen_id(gen_new_table_id,1);
end

И при вставке записи вызывать тригер, если нужно получить ID. Обычно, компоненты поддерживают вызов тригера автоматом. Если нет - ручками сами вызывайте.

Добавлено спустя 54 минуты 55 секунд:
Два раза тригер вставил, звиняйте.
create procedure sp_gen_new_table_id
returns (id integer)
as
begin
id = gen_id(gen_new_table_id, 1);
suspend;
end
Вот эту процедуру надо дергать перед вставкой записи и значение присваивать полю с ID.

Кстати, IBExpert так все сам называет, что вычислить имя процедуры можно по имени таблицы легко.
AkANz
новенький
Сообщения: 26
Зарегистрирован: 16.03.2010 12:59:02
Откуда: Алтайский край

Сообщение AkANz »

stikriz писал(а):Вот эту процедуру надо дергать перед вставкой записи и значение присваивать полю с ID.


А не получиться так, сработавший триггер сгенерирует ID 1 пользователю и в это же время 2 пользователь затеет вставку и ему так же будет сгенерирован этот же ID.
Мне бы хотелось получить ID после вставки записи.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Нет не получится! Проверенно "годами" :wink:
Аватара пользователя
Astralis
новенький
Сообщения: 45
Зарегистрирован: 06.06.2007 20:33:05
Откуда: Tvercity-Annet
Контактная информация:

Сообщение Astralis »

есть 2 варианта
1) zqHospitalInEdit.SQL.Text= 'INSERT INTO hospital_in (<вводимые поля>) 'VALUES (<вводимые значения>) RETURNING :ResultId';
результат получается что-то вроде zqHospitalInEdit.ParamByName('ResultId').AsInteger;
2) сделать в программе 2 компонента, первый будет вызывать sp_gen_new_table_id и получать значение первичного ключа, второй будет всталять это значение уже в запись. Это немного сложнее, зато гораздо гибче.
AkANz
новенький
Сообщения: 26
Зарегистрирован: 16.03.2010 12:59:02
Откуда: Алтайский край

Сообщение AkANz »

Astralis писал(а):есть 2 варианта
1) zqHospitalInEdit.SQL.Text= 'INSERT INTO hospital_in (<вводимые поля>) 'VALUES (<вводимые значения>) RETURNING :ResultId';
результат получается что-то вроде zqHospitalInEdit.ParamByName('ResultId').AsInteger;


RETURNING :ResultId у меня не захотел работать

Сделал по 2 варианту. Спасибо за помощь.
Ответить