Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вставка записей в таблицу InterBase [D7, IB6.x]


Страницы:   1 2

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. В данном случае это важно?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо