Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.09.18;
Скачать: [xml.tar.bz2];

Вниз

Вставка записей в таблицу InterBase   Найти похожие ветки 

 
asd   (2003-08-27 18:55) [0]

Привет! Подскажите пожалуйста как можно узнать при вставке ID записи, который присвоил генератор InterBase?


 
Calm   (2003-08-27 19:00) [1]

select max(id) from YourTable

Если же нужно одиним махом, то можно делать добавление через хранимую процедуру.
В ХП сделать один выходной параметр, который получать так:

NewID=gen_id(YourGenerator, 0); // текущее значение генератора


 
HSolo   (2003-08-27 19:02) [2]

Вариант 1: перед вставкой записи взять очередное значение генератора, и вставлять с уже известным значением.

Вариант 2: написать хранимую процедуру, к-рая вставляет запись и возвращает соотв.значение

Все прочее - от лукавого :)


 
HSolo   (2003-08-27 19:03) [3]

> select max(id) from YourTable

Вот так делать не надо. Можно сильно нарваться при интенсивной многопользовательской работе


 
Pat   (2003-08-27 23:58) [4]

>который присвоил генератор InterBase
Генератор ничего никому не присваивает

Вставлять значения на клиенте. IBX и FIBPlus поддерживают работу с генераторами для "autoinc" полей.

З.Ы. "autoinc" в кавычках :-)


 
asd   (2003-08-28 07:53) [5]

>Вариант 1: перед вставкой записи взять очередное значение генератора, и вставлять с уже известным значением

Скажите а как можно из программы вызвать это значение? (Хотя оно уже может измениться)

Опишу ситуацию. Происходит вставка записи и надо чтобы указатель в Gride стоял на вставленной записи. Но дело в том что частенько это не последняя запись (много народу работает).

Или подскажите пожалуйста пример хранимой процедуры, которая бы делала вставку и как получить от нее значение newid.

Заранее благодарен


 
Zacho   (2003-08-28 08:01) [6]


> asd (28.08.03 07:53) [5]

Если используешь IBX - то у TIBDataSet и TIBQuery есть св-во GeneratorField.
А в общем случае - в событии OnNewRecord выполнять запрос типа SELECT GEN_ID(MY_GEN,1) FROM RDB$DATABASE и полученное значение присваивать полю.


 
Жук   (2003-08-28 08:27) [7]


> asd (28.08.03 07:53) [5]
> Опишу ситуацию. Происходит вставка записи и надо чтобы указатель
> в Gride стоял на вставленной записи.

Append


 
HSolo   (2003-08-28 10:37) [8]

CREATE PROCEDURE INS_UPD_BAZA(
ID INTEGER,
FNAME VARCHAR(100),
FDATER DATE)
RETURNS (
IDENT INTEGER)
AS
BEGIN
if (id>0) then
begin
ident = id;
update baza set
fname = :fname, fdater = :fdater
where ident = :id;
end
else begin
ident = gen_id(g_baza, 1);
insert into baza(ident, fname, fdater)
values (:ident, :fname, :fdater);
end
suspend;
END


 
Zacho   (2003-08-28 10:40) [9]


> HSolo © (28.08.03 10:37) [8]

Можно, конечно, но толку-то от этого в IBX ? Только лишний гемморой.


 
AlexWeb   (2003-08-28 12:13) [10]

> Zacho © (28.08.03 08:01) [6]

А в общем случае - в событии OnNewRecord выполнять запрос типа SELECT GEN_ID(MY_GEN,1) FROM RDB$DATABASE и полученное значение присваивать полю.


Нефига не выйдет. Т.к. "GEN_ID(MY_GEN,1)" увеличит значение генератора "MY_GEN" на "1".


 
HSolo   (2003-08-28 12:15) [11]

1) Человек просил пример процедуры, что мне, жалко? :)
2) От ТАКОГО в точности - и впрямь лишний этот самый. Ну а если вставлять надо не в одну таблицу? У меня вообще-то в 4 штуки вставка идет, это просто кусок выдран для упрощения понимания :)
3) Я пользуюсь FIBPlus. В данном случае это важно?


 
HSolo   (2003-08-28 12:18) [12]

> "GEN_ID(MY_GEN,1)" увеличит значение генератора "MY_GEN" на "1".

Правильно. И при следующей вставке Вы получите СЛЕДУЮЩЕЕ значение генератора. Или не Вы, а другой пользователь. Тем самым гарантируется уникальность ID Ваших записей. На то и генератор :)
А Вам что нужно? Чтобы каждый раз возвращалось одно и то же? Ну, тогда GEN_ID(MY_GEN,0) - только зачем? Что Вы с этим делать будете?


 
AlexWeb   (2003-08-28 13:05) [13]

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 и присвоит его полю. Чё не так, а?


 
Zacho   (2003-08-28 13:11) [14]


> 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:25) [15]

> Zacho © (28.08.03 13:11) [14]
Сервер "сам" ничего не генерирует и не вставляет, тем более при коммите, просто триггера надо проавильно писать. Советую посмотреть http://www.ibase.ru/devinfo/generator.htm

А кто говорил, что "сервер вставляет", читайте внимательней "присвоит его полю". А насчет "Сервер "сам" ничего не генерирует", а кто генерирует, "Бабангидум" что ли? Триггер наверное срабатывает на сервере, а ни на клиенте!!!


 
HSolo   (2003-08-28 13:30) [16]

Уфф...
Если Вам нужно значение ID на клиенте - то см.Zacho © (28.08.03 08:01) [6] - и не утруждайте зря триггер, ничего никому там присваивать не надо! Клиент уже все присвоил, зачем второй раз-то?
Или есть опасения, что клиент все-таки не присвоит? Тогда в триггере:
if (new.id is null) then new.id = GEN_ID(MY_GEN,1);


 
Zacho   (2003-08-28 13:34) [17]


> 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


 
AlexWeb   (2003-08-28 13:35) [18]

Смотрите реальный пример:

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:41) [19]


> 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:49) [20]

Да ты пример пробовал свой, что пытаешься доказать мне?

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:56) [21]


> 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


 
Жук   (2003-08-28 13:59) [22]

Об чём спор-то ? У Zacho © абсолютно рабочий код. Единственное, что не могу понять, зачем этот гемор с генератором, если есть TIBDataSet ?


 
Zacho   (2003-08-28 14:02) [23]


> Жук © (28.08.03 13:59) [22]

Во-во. И св-во GeneratorField :)


 
HSolo   (2003-08-28 14:10) [24]

> AlexWeb (28.08.03 13:49) [20]
Да Zacho-то свой пример пробовал, не сомневайтесь. А вот пробовали ли Вы, что получится из Вашего AlexWeb (28.08.03 13:35) [18] если 2 пользователя попытаются одновременно вставить запись? Могу по шагам расписать, даже не пробуя :))


 
AlexWeb   (2003-08-28 14:12) [25]

> Жук © (28.08.03 13:59) [22]

Как будто я свой код не проверял!

"Жук ©" Тогда покажи, где ошибка в моем коде?


 
AlexWeb   (2003-08-28 14:14) [26]

> HSolo © (28.08.03 14:10) [24]
Могу по шагам расписать


Давай!


 
Zacho   (2003-08-28 14:19) [27]

2 AlexWeb:
Еще раз настоятельно рекомендую прочитать http://www.ibase.ru/devinfo/generator.htm


 
NickBat   (2003-08-28 14:20) [28]

to AlexWeb:

Текущее значение генератора 735.
Первый пользователь получил 735 и второй 735
Оба на клиенте сделали приращение на 1.
В итоге два пользователя пытаются записать ID=736

Дальше расписывать?


 
AlexWeb   (2003-08-28 15:08) [29]

Когда я использую Ваш пример то в результате получается:
- при выполнении запроса, ID = 735;
- при присвоении 735 полю и выполнении CommitRetaining условие в триггер IF срабатывает (значит оно = NULL)и генератор инкрементирует. Соотв., данному полю присваивается 736.

В чем сдесь проблема?


 
AlexWeb   (2003-08-28 15:11) [30]

Нашел в чем проблема!

В 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)

Все работает!



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.09.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.008 c
7-58947
sashak
2003-07-04 17:11
2003.09.18
HEX


1-58644
Modus
2003-09-08 13:34
2003.09.18
TStringGrid -> MS Excel


3-58575
Relaxxx
2003-08-26 14:58
2003.09.18
Попуп меню в ДБГриде


3-58583
Vitalygavrilov
2003-08-26 08:22
2003.09.18
Скажите пожалуйста как сделать правильно просмотр.


14-58908
Mr@MsGuns
2003-08-29 09:47
2003.09.18
Проект на Delphi 6 перевести в проект на Delphi 5





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский