Узнать значение ID только, что вставленной записи
Модератор: Модераторы
Узнать значение ID только, что вставленной записи
Есть необходимость узнать значение автоинкриментного 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 возвращаемое этим запросом.
В обработчике 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 возвращаемое этим запросом.
Возможно сработает zqHospitalInEdit.Active := True вместо zqHospitalInEdit.ExecSQL.
И далее, например, Label1.Caption := IntToStr(zqHospitalInEdit.Fields[0].AsInteger).
Lazarus 0.9.29 FPC 2.5.1 Win32
И далее, например, Label1.Caption := IntToStr(zqHospitalInEdit.Fields[0].AsInteger).
Lazarus 0.9.29 FPC 2.5.1 Win32
Спасибо, alex_rain.
Так сработало.
Так сработало.
alex_rain писал(а):Возможно сработает zqHospitalInEdit.Active := True вместо zqHospitalInEdit.ExecSQL.
Lazarus 0.9.29 FPC 2.5.1 Win32
есть еще zqHospitalInEdit.Open
или запросом получить текущее значение SEQUENCE для этой таблицы если конечно это поле у вас serial
Помогите, пожалуйста, теперь сделать то-же самое, т.е узнать значение 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 только, что вставленной записи?
Имеем (для примера лишнее убрано)
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 только, что вставленной записи?
Вообще, если с самого начала, то делать надо так:
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 так все сам называет, что вычислить имя процедуры можно по имени таблицы легко.
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 так все сам называет, что вычислить имя процедуры можно по имени таблицы легко.
stikriz писал(а):Вот эту процедуру надо дергать перед вставкой записи и значение присваивать полю с ID.
А не получиться так, сработавший триггер сгенерирует ID 1 пользователю и в это же время 2 пользователь затеет вставку и ему так же будет сгенерирован этот же ID.
Мне бы хотелось получить ID после вставки записи.
Нет не получится! Проверенно "годами" 
- Astralis
- новенький
- Сообщения: 45
- Зарегистрирован: 06.06.2007 20:33:05
- Откуда: Tvercity-Annet
- Контактная информация:
есть 2 варианта
1) zqHospitalInEdit.SQL.Text= 'INSERT INTO hospital_in (<вводимые поля>) 'VALUES (<вводимые значения>) RETURNING :ResultId';
результат получается что-то вроде zqHospitalInEdit.ParamByName('ResultId').AsInteger;
2) сделать в программе 2 компонента, первый будет вызывать sp_gen_new_table_id и получать значение первичного ключа, второй будет всталять это значение уже в запись. Это немного сложнее, зато гораздо гибче.
1) zqHospitalInEdit.SQL.Text= 'INSERT INTO hospital_in (<вводимые поля>) 'VALUES (<вводимые значения>) RETURNING :ResultId';
результат получается что-то вроде zqHospitalInEdit.ParamByName('ResultId').AsInteger;
2) сделать в программе 2 компонента, первый будет вызывать sp_gen_new_table_id и получать значение первичного ключа, второй будет всталять это значение уже в запись. Это немного сложнее, зато гораздо гибче.
Astralis писал(а):есть 2 варианта
1) zqHospitalInEdit.SQL.Text= 'INSERT INTO hospital_in (<вводимые поля>) 'VALUES (<вводимые значения>) RETURNING :ResultId';
результат получается что-то вроде zqHospitalInEdit.ParamByName('ResultId').AsInteger;
RETURNING :ResultId у меня не захотел работать
Сделал по 2 варианту. Спасибо за помощь.
