![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вставка записей в таблицу InterBase [D7, IB6.x]
asd © (2003-08-27 18:55:00)
Привет! Подскажите пожалуйста как можно узнать при вставке ID записи, который присвоил генератор InterBase?
AlexWeb (2003-08-28 15:11:00) [1]
Нашел в чем проблема!
В IBUpdateSQL.InsertSQL-е
insert into QL_CI
(NAME_FULL)
values
(:NAME_FULL)
небыло АвтоИнка в InsertSQL-е:
insert into QL_CI
(CI_ID, NAME_FULL)
values
(:CI_ID, :NAME_FULL)
Все работает!
AlexWeb (2003-08-28 15:08:00) [2]
Когда я использую Ваш пример то в результате получается:
- при выполнении запроса, ID = 735;
- при присвоении 735 полю и выполнении CommitRetaining условие в триггер IF срабатывает (значит оно = NULL)и генератор инкрементирует. Соотв., данному полю присваивается 736.
В чем сдесь проблема?
NickBat (2003-08-28 14:20:00) [3]
to AlexWeb:
Текущее значение генератора 735.
Первый пользователь получил 735 и второй 735
Оба на клиенте сделали приращение на 1.
В итоге два пользователя пытаются записать ID=736
Дальше расписывать?
Zacho (2003-08-28 14:19:00) [4]
2 AlexWeb:
Еще раз настоятельно рекомендую прочитать http://www.ibase.ru/devinfo/generator.htm
AlexWeb (2003-08-28 14:14:00) [5]
> HSolo © (28.08.03 14:10) [24]
Могу по шагам расписать
Давай!
AlexWeb (2003-08-28 14:12:00) [6]
> Жук © (28.08.03 13:59) [22]
Как будто я свой код не проверял!
"Жук ©" Тогда покажи, где ошибка в моем коде?
HSolo (2003-08-28 14:10:00) [7]
> AlexWeb (28.08.03 13:49) [20]
Да Zacho-то свой пример пробовал, не сомневайтесь. А вот пробовали ли Вы, что получится из Вашего AlexWeb (28.08.03 13:35) [18] если 2 пользователя попытаются одновременно вставить запись? Могу по шагам расписать, даже не пробуя :))
Zacho (2003-08-28 14:02:00) [8]
> Жук © (28.08.03 13:59) [22]
Во-во. И св-во GeneratorField :)
Жук (2003-08-28 13:59:00) [9]
Об чём спор-то ? У Zacho © абсолютно рабочий код. Единственное, что не могу понять, зачем этот гемор с генератором, если есть TIBDataSet ?
Zacho (2003-08-28 13:56:00) [10]
> AlexWeb (28.08.03 13:49) [20]
Привести тебе пример из рабочего (причем давно и успешно работающего) проекта ? Вот:
procedure TfmSprav.ibdsSpravNewRecord(DataSet: TDataSet);
begin
sqlID.ExecQuery;
ibdsSprav.FieldByName("ID_OS").Value:=sqlID.FieldByName("ID").Value;
sqlID.Close;
end;
А вот запрос в sqlID.SQL - SELECT GEN_ID(GEN_OS,1) FROM RDB$DATABASE
AlexWeb (2003-08-28 13:49:00) [11]
Да ты пример пробовал свой, что пытаешься доказать мне?
procedure TForm1.IBQuery1NewRecord(DataSet: TDataSet);
var
i: integer;
begin
IBQuery_Temp.SQL.Text:= "SELECT GEN_ID(GEN_QL_CI_ID,1) FROM RDB$DATABASE";
IBQuery_Temp.Open;
i:= IBQuery_Temp.Fields [0].asinteger;
IBQuery_Temp.Close;
IBQuery1.FieldByName ("CI_ID").asinteger:= i;
end;
Сначало думай (проверь код на выполнение), а потом говори!!!
Zacho (2003-08-28 13:41:00) [12]
> AlexWeb (28.08.03 13:35) [18]
Категорически не согласен с таким примером ! Очень большая вероятность нарушения ПК при многопользовательской работе.
Правильно - так:
procedure TForm1.IBQuery1NewRecord(DataSet: TDataSet);
var
i: integer;
begin
IBQuery_Temp.SQL.Text:= "SELECT GEN_ID(GEN_QL_CI_ID, 1) FROM RDB$DATABASE";
IBQuery_Temp.Open;
i:= IBQuery_Temp.Fields [0].asinteger;
IBQuery_Temp.Close;
IBQuery1.FieldByName ("CI_ID").asinteger:= i;
end;
Только я бы для запроса вместо TIBQuery использовал TIBSQL.
AlexWeb (2003-08-28 13:35:00) [13]
Смотрите реальный пример:
procedure TForm1.IBQuery1NewRecord(DataSet: TDataSet);
var
i: integer;
begin
IBQuery_Temp.SQL.Text:= "SELECT GEN_ID(GEN_QL_CI_ID,0) FROM RDB$DATABASE";
IBQuery_Temp.Open;
i:= IBQuery_Temp.Fields [0].asinteger;
IBQuery_Temp.Close;
IBQuery1.FieldByName ("CI_ID").asinteger:= i+1;
end;
Или Вы не согласны? ;-)
> Zacho © (28.08.03 13:11) [14]
А это как "просто триггера надо проавильно писать"? Чё, там много надо писать что ли?
Zacho (2003-08-28 13:34:00) [14]
> AlexWeb (28.08.03 13:25) [15]
Так я же сказал : "триггера надо правильно писать".
Например, так:
CREATE TRIGGER MY_TABLE_BI0 FOR AMORT_GROUPS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
if (new.ID is NULL) then new.ID=GEN_ID(MY_GEN,1);
end
HSolo (2003-08-28 13:30:00) [15]
Уфф...
Если Вам нужно значение ID на клиенте - то см.Zacho © (28.08.03 08:01) [6] - и не утруждайте зря триггер, ничего никому там присваивать не надо! Клиент уже все присвоил, зачем второй раз-то?
Или есть опасения, что клиент все-таки не присвоит? Тогда в триггере:
if (new.id is null) then new.id = GEN_ID(MY_GEN,1);
AlexWeb (2003-08-28 13:25:00) [16]
> Zacho © (28.08.03 13:11) [14]
Сервер "сам" ничего не генерирует и не вставляет, тем более при коммите, просто триггера надо проавильно писать. Советую посмотреть http://www.ibase.ru/devinfo/generator.htm
А кто говорил, что "сервер вставляет", читайте внимательней "присвоит его полю". А насчет "Сервер "сам" ничего не генерирует", а кто генерирует, "Бабангидум" что ли? Триггер наверное срабатывает на сервере, а ни на клиенте!!!
Zacho (2003-08-28 13:11:00) [17]
> HSolo © (28.08.03 12:15) [11]
Согласен :)
> AlexWeb (28.08.03 13:05) [13]
> HSolo © (28.08.03 12:18) [12]
>
> То это все неправильно. Вы два раза увеличиваете знач. ген.
> Пример: в п.1 вы получили значение ген. MY_GEN=100 и присвоили
> его полю, а в п.2 при "коммите" сервер сам сгенерирует значение
> MY_GEN=101 и присвоит его полю. Чё не так, а?
Вот как раз так - правильно. Сервер "сам" ничего не генерирует и не вставляет, тем более при коммите, просто триггера надо проавильно писать. Советую посмотреть http://www.ibase.ru/devinfo/generator.htm
AlexWeb (2003-08-28 13:05:00) [18]
HSolo © (28.08.03 12:18) [12]
Если событии "OnNewRecord" Вы сначала вызовите:
1. "SELECT GEN_ID(MY_GEN,1) FROM RDB$DATABASE";
2. а потом вставите запись с этим значение ген.
То это все неправильно. Вы два раза увеличиваете знач. ген.
Пример: в п.1 вы получили значение ген. MY_GEN=100 и присвоили его полю, а в п.2 при "коммите" сервер сам сгенерирует значение MY_GEN=101 и присвоит его полю. Чё не так, а?
HSolo (2003-08-28 12:18:00) [19]
> "GEN_ID(MY_GEN,1)" увеличит значение генератора "MY_GEN" на "1".
Правильно. И при следующей вставке Вы получите СЛЕДУЮЩЕЕ значение генератора. Или не Вы, а другой пользователь. Тем самым гарантируется уникальность ID Ваших записей. На то и генератор :)
А Вам что нужно? Чтобы каждый раз возвращалось одно и то же? Ну, тогда GEN_ID(MY_GEN,0) - только зачем? Что Вы с этим делать будете?
HSolo (2003-08-28 12:15:00) [20]
1) Человек просил пример процедуры, что мне, жалко? :)
2) От ТАКОГО в точности - и впрямь лишний этот самый. Ну а если вставлять надо не в одну таблицу? У меня вообще-то в 4 штуки вставка идет, это просто кусок выдран для упрощения понимания :)
3) Я пользуюсь FIBPlus. В данном случае это важно?