Форум: "Базы";
Текущий архив: 2002.04.04;
Скачать: [xml.tar.bz2];
ВнизВопрос по IB Найти похожие ветки
← →
Turalyon (2002-03-12 12:09) [0]Помогите пожалуйста.
Проблемма такая. Вот кусок кода.... Задача примерно следуящая - пройти по таблице, если уже существует запись с C_NAME равным определенному значению, то просто запомнить ее ключ, если нет, что добавить запись с таким именем. Соответственно компонент IBQuery для поиска, IBDataSet для непосредственного добавления в базу... Оба подключены к одной IBDatabase и Одной IBTransaction (но я пробывал их и разносить...)
Вот запускаю прогу... Access violation... Иду Trace-ом все работает. Лезу и добавляю запись 1 любую в базу (изначально она пустая) все работает и просто через запуск, без всяких Trace. Вроде надо радоваться что работает, но хочется узнать где собака порылась...???? Подскажите пожалуйста...
DataSource1.DataSet.Open;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add("select * from computer");
IBQuery1.SQL.Add("where C_NAME = """ + CompName + """");
IBQuery1.Open;
if IBQuery1.IsEmpty then
begin
IBDataSet1.Insert;
IBDataSet1.FieldByName("C_NAME").AsString := CompName;
IBDataSet1.Post;
CompId := IBDataSet1.FieldByName("C_id").AsInteger;
end
else CompId := IBQuery1.FieldByName("C_id").AsInteger;
← →
Johnmen (2002-03-12 12:37) [1]А не проще ли вместо IBDataSet использовать просто IBQuery2, который INSERT INTO ... ?
← →
Turalyon (2002-03-12 12:48) [2]>Johnmen ©
Не знаю... не пробовал пока. Дело в том что способ работы через IBDataSet был первым примером, который я нашел... в примерах. Вот я и стал использовать его.
← →
gek (2002-03-12 13:00) [3]Johnmen © (12.03.02 12:37) прав, IBQuery надо использовать
← →
Turalyon (2002-03-12 13:06) [4]>gek
>Johnmen ©
А почему??? Чем он лучше чем IBDataSet?
← →
Johnmen (2002-03-12 13:10) [5]Ну зачем же использовать DataSet, если хочешь просто выполнить запрос, а не работать с набором данных !?
← →
Turalyon (2002-03-12 13:45) [6]ОК. Переделал сделал через еще одно IBQuery
Вот такой стал текст
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add("select * from computer");
IBQuery1.SQL.Add("where C_NAME = """ + CompName + """");
IBQuery1.Open;
if IBQuery1.IsEmpty then
begin
IBQuery2.ParamByName("C_NAME").AsString := CompName;
IBQuery2.ExecSQL;
Приходится еще раз закрывать IBQuery1 что бы получить ID т.к. во втором Query SQL запрос след
insert into COMPUTER
(C_NAME)
values
(:C_NAME)
C_id - автоинкрементное поле реализовано триггером
IBQuery1.Close;
IBQuery1.Open;
CompId := IBQuery1.FieldByName("C_id").AsInteger;
end
else CompId := IBQuery1.FieldByName("C_id").AsInteger;
Эта доп. Закрытие открытие не будет ли тормозить систему?
Да забыл дописать в таком виде все работает.
← →
Johnmen (2002-03-12 13:59) [7]Если правильно уловил смысл того, что ты в итоге хочешь, то :
используй для всего этого один IBDataSet с прописанными соответствующем образом SelectSQL, InsertSQL, ModifySQL, RefreshSQL...
← →
Turalyon (2002-03-12 14:13) [8]>Johnmen ©
Именно так я и делал все прописал, все SQL запросы, описал что необходимо делать с генератором....
Самый первый пример работает, если в Таблице есть хоть одна запись... или в пошаговом режиме, а по другому - Access violation....
← →
Johnmen (2002-03-12 14:19) [9]>...описал что необходимо делать с генератором...
Не понял...
А где возникает AV ? ; по идее, должно работать, независимо от того, сколько записей получено...
← →
Val (2002-03-12 14:21) [10]почему не включить поле C_NAME в уникальный индекс, к примеру?
← →
Turalyon (2002-03-12 14:53) [11]>Johnmen ©
>Не понял...
IBDataSet.GeneratorField.
Я недавно задавал вопрос по поводу триггеров и генераторов. Если их не описать в этом свойстве, то были проблеммы - прога ругалась - говорила что надо присвоить значение этому полю (ключевому, автоинкрементному), которое задавалось триггером. И присвоить можно было что угодно... но не закрывая транзакцию нельзя было узнать что именно присваивалось (в смысле физически в таблицу заносилось)...
>Val ©
Дык оно у меня уникальное и есть... вот как она создавалась (таблица)
CREATE TABLE "COMPUTER"
(
"C_ID" DECIMAL(18, 0) NOT NULL,
"C_NAME" VARCHAR(40) CHARACTER SET WIN1251 NOT NULL,
PRIMARY KEY ("C_ID"),
UNIQUE ("C_NAME")
);
← →
Turalyon (2002-03-12 15:03) [12]>Johnmen ©
Забыл дописать - AV выскакивает вообще ни на что конкретное не показывая.... если заремарить кусок написаный в 1 сообщениии все работает (в смысле программа), но ничего не делает (в смысле с базой) :)
← →
Val (2002-03-12 15:10) [13]если уникальное, зачем тогда делать проверку на существование? Сервер с этим сам справится :) и выкинет вам сообщение.
← →
Turalyon (2002-03-12 15:24) [14]>Val ©
Дело в том что программа будет висеть как сервис и должна все делать в автоматическом режиме, без вмешательства пользователя... И ее ругань мне никчему... :)
← →
Johnmen (2002-03-12 15:26) [15]>Я недавно задавал вопрос по поводу триггеров и генераторов.
>Если их не описать в этом свойстве, то были проблеммы - прога
>ругалась - говорила что надо присвоить значение этому полю
>(ключевому, автоинкрементному), которое задавалось триггером. И
>присвоить можно было что угодно... но не закрывая транзакцию
>нельзя было узнать что именно присваивалось (в смысле физически
>в таблицу заносилось)...
Это полная ерунда ! Если у тебя прописан триггер BEFORE INSERT и в нем увеличиваешь значение соотв. поля...вобщем классически...
и при этом в проге присваиваешь любое знач.полю, и выполняешь Post (явно или неявно) и прописано как надо RefreshSQL, ТО !
После вызова IBDataSet.Refresh увидишь , что реально прописалось в таблицу !
← →
Turalyon (2002-03-12 15:42) [16]>Johnmen ©
Если не завершать транзакцию, то ничего не увидишь...
Тригер прописан был Before Insert все класически ....
Вот RefteshSQL
Select
C_ID,
C_NAME
from COMPUTER
where
C_ID = :C_ID
После вызова IBDataSet1.Refresh ничего не изменялось.
← →
Scalia (2002-03-12 16:06) [17]>Если не завершать транзакцию, то ничего не увидишь...
Да ничего подобного !
>После вызова IBDataSet1.Refresh ничего не изменялось.
Естественно - ведь значение параметра :C_ID равно тому значению поля, которое у текущей записи НД, а оно - от балды...
Вот RefteshSQL
Select
C_ID,
C_NAME
from COMPUTER
where
C_NAME = :C_NAME
← →
Johnmen (2002-03-12 16:08) [18]Scalia - это пседвоним Johnmen"a для Malder"a ...
← →
Turalyon (2002-03-13 08:26) [19]>Johnmen ©
Ты прав. Так работает.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.04.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.006 c