Форум: "Базы";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
ВнизКак найти редактируемую запись после Commit а Найти похожие ветки
← →
ProgC (2004-02-27 07:37) [0]Мастера помогите решить проблемму. Как сделать редактируемую запись текущей после Commit? Искать с помощью Lookup, по уникальному полю ID нельзя, т.к. до выполнения подтвердения транзакции, ID прочитать не удается.
Использую IBX.
← →
ЮЮ © (2004-02-27 07:40) [1]> Как сделать редактируемую запись текущей после Commit
Неужели Commit изменяет текущую запись DataSet-а ?
← →
Zacho © (2004-02-27 08:06) [2]Настоятельно рекомендую прочитать http://www.ibase.ru/devinfo/generator.htm
← →
ProgC (2004-02-27 08:54) [3]>Неужели Commit изменяет текущую запись DataSet-а ?
Commit вообще закрывает DataSet
← →
Zacho © (2004-02-27 08:57) [4]И правильно делает. Еще есть CommitRetaining.
И все-таки, проблема у тебя не в Commit"е, а в неправильной вставке значения ПК (в триггере, угадал ?) Еще раз настоятельно советую внимательно прочитать http://www.ibase.ru/devinfo/generator.htm
← →
ProgC (2004-02-27 10:11) [5]Я знаю, что проблемма не в Commit"е. Проблема во мне. Прочитал http://www.ibase.ru/devinfo/generator.htm.
Думаю надо делать так:
1. получать текущее значение генератора
2. сделать Commit
3. искать запись по значению, которое мы получили в шаге №1.
Я все правильно понял? или мы говорим о разных вещах?
← →
Sergey13 © (2004-02-27 10:17) [6]2ProgC (27.02.04 10:11) [5]
Между 1 и 2 сделать инсерт не забудь. 8-)
← →
ProgC (2004-03-01 08:16) [7]Извеняюсь за долгое отсутствие (Инет отрубили на время).
Но это громозко, не стабильно при многопользовательской работе.
А что если использовать Bookmarks? я пробывал, но опять же с этими транзакциями, что то не работает. Есть какие нибудь еще варианты?
← →
Deniz © (2004-03-01 08:40) [8]Генераторы гарантируют(кол-во значений хватит надолго) уникальность при многопользовательской работе!
> Но это громозко ...
???
Для генераторов в IBX есть специальное поле, которое настраивает момент получения нового значения генератора(на сервере/после добавления/перед постом), выбери для себя что-нибудь :-) зависит от задачи.
var i : integer;
...
i:=IBQuery1.FieldByName("ID").AsInteger;
...
IBQuery1.Locate("ID", i, []);
Добавляется всего 3(три) строчки!
← →
Vemer © (2004-03-01 14:27) [9]Как вариант..
Procedure Sklad_Refresh(Tovar_Int:Variant);
Begin
Sklad.Close;
Sklad.Open;
{Sklad.Fetchall}
Sklad.Locate("Tovar_ID",Tovar_Int,[]);
End;
..
Sklad_Refresh(SkladTovar_ID.Value);
..
← →
VLAD-MAL (2004-03-01 14:32) [10]
Но это громозко, не стабильно при многопользовательской работе.
А что если использовать Bookmarks? я пробывал, но опять же с этими транзакциями, что то не работает. Есть какие нибудь еще варианты?
1. Генераторы работают вне контекста транзакций, что гарантирует уникальность номеров.
2. Громоздко - юзай IBX или FIB+ - там это дело встроено. 3. Используй TIBDataSet/TpFIBDataSet !!! Все твои рефреши будут делаться автоматом.
4. Так делают все мои знакомые программеры и я (я их достал советами, им просто деваться некуда было) :) :) :)
← →
kaif © (2004-03-01 15:10) [11]Удавил бы того, кто первый порекомендовал значение генератора в триггере получать... И еще того, кто любит уверять, что CommitRetaining - плохой способ подтверждать транзакции. Все это неправда. Есть еще одна байка, которую я пока никак эмпирически не могу подтвердить. Байка о том, что размер страницы базы данных под NTFS должен быть обязательно 4K. Я юзал и 1K и 4K. Никакой разницы, кроме той, что при 1K файл базы явно меньше, а скорость запросов - выше, я не заметил. Вообще нужно создать специальную страницу в сети: "IB и общепринятые недоразумения вокруг него".
← →
VLAD-MAL (2004-03-01 15:28) [12]Удавил бы того, кто первый порекомендовал ...
Похоже, что мне - кирдык... Единственная надежда, что я - не "первый, кто ...".
А лично я еще ненавижу переходить дорогу на зеленый свет и уступать дорогу бульдозеру, когда на велосипеде катаюсь. Но, к счастью, к теме вопроса это не относится.
← →
Vlad © (2004-03-01 15:34) [13]
> kaif © (01.03.04 15:10) [11]
> Вообще нужно создать специальную страницу в сети: "IB и
> общепринятые недоразумения вокруг него".
Есть уже нечто подобное
http://www.ibase.ru/devinfo/ibmyths.htm
← →
ProgC (2004-03-01 19:29) [14]Вот тригер:
CREATE TRIGGER AGENTS_ORG_BI FOR AGENTS_ORG
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_AGENTS_ORG_ID,1);
END;
Вот код Delphi:
var
i: integer;
begin
IBQuery_Agents.Post;
i:=IBQuery_Agents.FieldValues["ID"];
IBQuery_Agents.Transaction.Commit;
IBQuery_Agents.Active:=True;;
IBQuery_Agents.Locate("ID",i,[]);
end;
Результат:
Выдает на том месте где идет присвоение переменной i значания ID ошибку. "Не могу конвертировать Null в Integer". Тригер полностью рабочий.
← →
VLAD-MAL (2004-03-01 20:03) [15]var
i: integer;
begin
IBQuery_Agents.Post;
i:=IBQuery_Agents.FieldValues["ID"];
IBQuery_Agents.Transaction.Commit;
IBQuery_Agents.Active:=True;;
IBQuery_Agents.Locate("ID",i,[]);
end;
Как я зол!
1. Ты что от TQuery хочешь? Она всего сразу не может! Либо Select, либо Update/Delete/Insert! Юзай TIBDataSet! Он делает все, в том числе и пожет получить очередное значение генератора ПЕРЕД .Post, сразу после .Insert
А если хочешь TIBQuery, то последовательно меняй параметры SQL - запроса:
- "select gen_id(GenName, 1) from RDB$DATABASE" // Получение значения очередного Id
- "insert into ... " // Занесение значений
- "select ... where id = :id" // Рефреш
2. i:=IBQuery_Agents.FieldValues["ID"].AsInteger;
3.Юзай TIBDataSet!
← →
ProgC (2004-03-02 07:39) [16]VLAD-MAL, я знаю, ты очень зол и у тебя есть причина на это. Но есть одно смягчающее обстоятельство, я действовал по примеру, который дал Deniz. Не злись на меня, не надо...
По поводу твоего 2-го замечания. Поле ID имеет тип Integer, и при доступе к его значению через IBQuery_Agents.FieldValues["ID"] Возвращаеться не строка, а число типа Integer. Или я не прав? Поэтому принципиальной разници я не вижу.
← →
VLAD-MAL (2004-03-02 16:56) [17]Поле ID имеет тип Integer, и при доступе к его значению через IBQuery_Agents.FieldValues["ID"] Возвращаеться не строка, а число типа Integer. Или я не прав? Поэтому принципиальной разници я не вижу.
Поле имеет тип Integer в базе.
Поле FieldValues["ID"] имеет тип Variant в твоей программе. И при присваивании Integer := Variant все будет шоколадно, пока Variant имеет целое значение. Null - не целое.
Так что всегда пиши:
i := IBQuery_Agents.FieldByName("ID").AsInteger;
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.031 c