Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.04.04;
Скачать: CL | DM;

Вниз

Вопрос по 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.013 c
1-9549
Kostyanych
2002-03-23 00:46
2002.04.04
А как реализовать drag&drop из, например, проводника в свою прогу?


1-9584
snoup
2002-03-23 20:13
2002.04.04
Как изменить шрифт у заголовка окна?


4-9683
Basaev
2002-02-03 03:52
2002.04.04
Как закрыт другую програму из своей


1-9442
dth
2002-03-25 11:46
2002.04.04
Окошко как в Delphi при ошибках кода


14-9650
Оля
2002-02-20 17:26
2002.04.04
Как быстро и без особых проблем создать help к программе?