Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.005 c
3-9360
Igor_
2002-03-11 14:55
2002.04.04
Grant to ALL в InterBase


1-9551
новыйенкий
2002-03-23 20:10
2002.04.04
Нужна помощь


3-9415
lightix
2002-03-12 16:16
2002.04.04
Как вывести в отчет все поля запроса, если их количество непостоянно?


3-9367
Slawik
2002-03-11 13:25
2002.04.04
---|Ветка была без названия|---


1-9443
Gayrus
2002-03-22 17:28
2002.04.04
String





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский