Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Обновление, изменение данных через IBDataSet


Автор: holodnaya 9.11.2009, 20:09
Кто хорошо знаком с компонентами, позволяющими работать Delphi с FireBird, подскажите, пожалуйста, как лучше сделать.
В одной форме у меня таблица с выведеными данными по студентам (Использую cxGrid, соединенный с IBDataSet1). А редактирование и добавление новых данных происходит в другой форме (в основном, используются DBEdit-ы). Для того, чтобы во второй форме отображались данные по выбранному студенту, DBEdit- ы соединяю с тем же IBDataSet1. 
в IBDataSet1 запрос только на выборку данных (SelectSQL). При этом я понимаю, что с таким запросом через IBDataSet1 с данными кроме выбора ничего больше сделать нельзя. Задаю запросы Insert/Update/Delete/Refresh, и программа ругается... 
 
Код

Dynamic SQL Error 
SQL error code = -104
Token unknown - line 1, char 169
WORK.

При этом меня смущает, что все эти запросы хранятся одновременно в соответсвующих свойствах SelectSQL, InsertSQL и т.д. 
Вопрос №1. Как же всё-таки правильно сделать? Сразу их задавать или по мере необходимости (при вызове определённой процедуры и соответсвенно в коде писать)? 
И ещё вычитала одно замечание, что при использовании IBDataSet для выборки данных, их изменение и добавление лучше проводить через IBQuery... но тогда придётся ручками код прописывать для вывода данных на вторую форму.
Вопрос №2Каким способом (с помощью какого компонента) лучше и правильнее изменять данные (при этом нужно учесть, что данные редактируются не в самой таблице, а в другой форме).

Автор: holodnaya 9.11.2009, 23:29
Ура! Мне удалось решить  один вопрос 
Все запросы SelectSQL, InsertSQL... действительно нужно устанавливать в IBDataSet одновременно (наверное, в нужное время они вызываются как у IBTable, только у IBTable запросы формируются автоматически, а здесь можно самим формировать). Причем, очень важно, чтобы последовательность полей в Insert была такой же как в базе (генератором запроса может и в другом порядке сформироваться). 
А ошибка выходила потому, что имя поля "WORK" по каким-то причинам не понравилось компоненту, обращающемуся из делфи к базе (наверное, зарезервированное слово... smile  ) 
А вот на вопрос, каким компонентом правильнее изменять данные IBDataSet или IBQuery, я всё же надеюсь получить ответ )

Автор: Данкинг 9.11.2009, 23:44
Цитата(holodnaya @  9.11.2009,  23:29 Найти цитируемый пост)
IBQuery

Я бы предпочёл Query - для того он и придуман, в конце концов. smile 

Автор: former 10.11.2009, 14:31
Цитата(holodnaya @  9.11.2009,  23:29 Найти цитируемый пост)
А ошибка выходила потому, что имя поля "WORK" по каким-то причинам не понравилось компоненту, обращающемуся из делфи к базе (наверное, зарезервированное слово... smile  )

Именно так оно и есть.
Цитата(holodnaya @  9.11.2009,  23:29 Найти цитируемый пост)
А вот на вопрос, каким компонентом правильнее изменять данные IBDataSet или IBQuery, я всё же надеюсь получить ответ )

Это уже как кому больше нравится.
IBDataSet по большому счету - это совокупность нескольких IBQuery. Можно вообще пользоваться одним IBQuery и формировать запросы в тексте программы.
Вот Данкинг-у удобней IBQuery, а мне IBDataSet, т.к. использую FibPlus. smile 

Автор: holodnaya 10.11.2009, 23:05
Цитата(former @  10.11.2009,  14:31 Найти цитируемый пост)
Вот Данкинг-у удобней IBQuery, а мне IBDataSet,

IBDataSet проще использовать, но тогда не очень красиво получается, в одной форме добавляешь данные или редактируешь, в общей таблице видны сразу все изменения. 
Как сделать так, чтобы изменения в таблице были видны только после закрытия Формы редактирования?
Если использую IBQuery и пишу такой код (при нажатии на кнопочку "Изменить данные")  
Код

procedure TFMain.Button2Click(Sender: TObject);
begin
   FStudent := TFStudent.Create(Application);
   DM.IBQuery1.ParamByName('ID_STUDENT').AsInteger := StrToInt(cxGrid1DBBandedTableView1.Controller.FocusedRow.Values[0]);

   Query := 'select pole1, pole2, pole3 from Table1 WHERE id_student = :ID_STUDENT';

   DM.IBQuery1.SQL.Clear;
   DM.IBQuery1.SQL.Add(Query);
   DM.IBQuery1.ExecSQL;  // на этой строке выдает ошибку
   DM.IBQuery1.Close;
   FStudent.ShowModal;

end;


получаю ошибку 
Код

Project Student.exe raised exception class EIBInterBaseError with message 'Dynamic SQL Error
SQL error code = -206
Column unknown
ID_STUDENT
unknown ISC error 336397208'.

Или как устранить эту ошибку и в чем причина её возникновения?



Автор: Данкинг 10.11.2009, 23:33
Цитата(holodnaya @  10.11.2009,  23:05 Найти цитируемый пост)
IBDataSet проще использовать, 

Кому как. smile 

Цитата(holodnaya @  10.11.2009,  23:05 Найти цитируемый пост)
Код

Query := 'select pole1, pole2, pole3 from Table1 WHERE id_student = :ID_STUDENT';

Значение параметра присваивай после DM.IBQuery1.SQL.Add(Query). smile 


Автор: holodnaya 10.11.2009, 23:49
Цитата(Данкинг @  10.11.2009,  23:33 Найти цитируемый пост)
Значение параметра присваивай после DM.IBQuery1.SQL.Add(Query). 

Я только что опробовала эту последовательность, но ошибка не исчезла... 

Автор: Данкинг 11.11.2009, 00:10
Эмм... holodnaya, текст ошибки читала?
Цитата

Column unknown
ID_STUDENT

Автор: holodnaya 11.11.2009, 00:17
Цитата(Данкинг @  11.11.2009,  00:10 Найти цитируемый пост)
Эмм... holodnaya, текст ошибки читала?

Читала, но из этого я не могу понять причину её возникновения.

Автор: Данкинг 11.11.2009, 00:18
Цитата(holodnaya @  11.11.2009,  00:17 Найти цитируемый пост)
Читала, но из этого я не могу понять причину её возникновения.

Как переводится сообщение об ошибке?

Автор: holodnaya 11.11.2009, 00:24
Цитата(Данкинг @  11.11.2009,  00:18 Найти цитируемый пост)
Как переводится сообщение об ошибке?

С английским у меня, конечно, не очень... Но я так понимаю, что столбец ID_STUDENT неизвестен (то есть не найден)...
Я понимаю, если бы в заспросе было несколько таблиц и в каждой из них было одинаковое поле, но здесь-то одна таблица и поле там такое точно есть

Автор: Данкинг 11.11.2009, 00:28
Цитата(holodnaya @  11.11.2009,  00:24 Найти цитируемый пост)
поле там такое точно есть

Тогда попробуй:
1) Вызывать DM.IBQuery1.Close перед DM.IBQuery1.SQL.Clear
2) Переименовать параметр ID_STUDENT, чтобы он не совпадал с названием поля.

Добавлено через 56 секунд
Да, и вообще, с запросами SELECT... используется DM.IBQuery1.Open, а не DM.IBQuery1.ExecSQL. smile 

Автор: holodnaya 11.11.2009, 00:38
Код

  Query := 'Select pole1, pole2, pole3 from STUDENT  WHERE ID_STUDENT = :param';
   DM.IBQuery1.Close;
   DM.IBQuery1.SQL.Clear;
   DM.IBQuery1.SQL.Add(Query);
   DM.IBQuery1.ParamByName('param').AsString := cxGrid1DBBandedTableView1.Controller.FocusedRow.Values[0];
   DM.IBQuery1.Open;
 

Выдает ошибку, что парамерт param не найден.
А его не надо изначально ещё как-то объявлять, прежде чем устанавливать туда значение?

Автор: Данкинг 11.11.2009, 00:43
Бывает такая тупость, как "параметр не найден"... В таких случаях я делаю просто:

   
Код

Query := 'Select pole1, pole2, pole3 from STUDENT  WHERE ID_STUDENT ="'+cxGrid1DBBandedTableView1.Controller.FocusedRow.Values[0]+'"';
   DM.IBQuery1.Close;
   DM.IBQuery1.SQL.Clear;
   DM.IBQuery1.SQL.Add(Query);
   DM.IBQuery1.Open;

 smile 

Автор: holodnaya 11.11.2009, 00:51
Я тоже так делаю иногда )))
Нашла как здесь справиться, нужно просто у свойства ParamCheck = true, так как используются параметры в запросе
Спасибо за советы, Данкинг!

Автор: Данкинг 11.11.2009, 01:48
Цитата(holodnaya @  11.11.2009,  00:51 Найти цитируемый пост)
Нашла как здесь справиться, нужно просто у свойства ParamCheck = true, так как используются параметры в запросе

Не знал, учту на будущее.  smile 

Цитата(holodnaya @  11.11.2009,  00:51 Найти цитируемый пост)
Спасибо за советы, Данкинг!

Взаимно спасибо за ParamCheck. smile 

Автор: holodnaya 17.11.2009, 23:57
Не закрывала тему до тех пор, пока не реализовала все операции: удаление, изменение, добавление данных в базу. Очень удобно производить все изменения используя IBQuery, хотя IBDataSet мне изначально показался проще  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)