Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > ADO+MS Access: помогите разобраться!


Автор: Rowi 19.2.2006, 01:29
Здравствуйте, все!

Такая ситуация:
Наконец дошли руки до БД (в самой Delphi кое-что уже умею). Через TTable(BDE) по мелочи простейшие вещи получались. Но чтобы уйти от BDE (из-за необходимости при распространении таскать за собой кучу всякого), решил попробовать связку Delphi+ADO(Jet.OLEDB.4.0)+MS Access.

Сделал в самом Access'e тренировочную базочку на 3 таблички: "Сотрудники"(КодСотрудника, ФамилияСотрудника), "Клиенты"(КодКлиента, ФамилияКлиента), "Заказы"(КодЗаказа, КодКлиента, КодСотрудника, ДатаРазмещения).
Для того, чтобы подсмотреть ;) содержание запроса, там же создал запрос "ЗаказыЗапрос", чтобы выдавал то же, что и таблица "Запрос", но вместо "КодКлиента" и "КодСотрудника" подставлял соответственно Фамилии того и другого.

Подсмотренный текст запроса такой:
Код

SELECT Заказы.КодЗаказа, Заказы.ДатаРазмещения, Клиенты.ФамилияКлиента, Сотрудники.ФамилияСотрудника
FROM Сотрудники INNER JOIN (Клиенты INNER JOIN Заказы ON Клиенты.КодКлиента = Заказы.КодКлиента) ON Сотрудники.КодСотрудника = Заказы.КодСотрудника
ORDER BY Заказы.КодЗаказа;

В самом Access'e всё работает прекрасно: в таблицу выводится нужная информация, можно редактировать и добавлять записи.

Далее пробовал то же самое и через TADOQuery, и через TADODataSet(кстати, так и не понял, что лучше использовать?). Запрос с тем же "плагиатным" текстом вроде работает (информация в TDBGrid выводится правильная и даже получается что-то редактировать), но не могу добавлять записи!
Т.е. они вроде вводятся и сохраняются(?), но при повторном применении того же запроса (для обновления данных) новых записей нет!

Проверяю через Access - в таблицах "Сотрудники" и "Клиенты" новые записи есть (правда, дублирует фамилию столько раз, сколько ей должно быть сопоставлено Заказов) , а в "Заказах" тоже новые записи есть, но поля "КодКлиента" и "КодСотрудника" пустые. Видимо поэтому новый запрос их и не видит?

Помогите пожалуйста разобраться - что я не так делаю?

Заранее спасибо!

Автор: YurikGL 19.2.2006, 22:52
Цитата

и через TADODataSet(кстати, так и не понял, что лучше использовать?).

Лучше TADODataSet... Глюков меньше.


Цитата

но не могу добавлять записи!

Больно сложный запрос для добавления... я бы lookup поля использовал. Т.е. двойной клик на adodataset, правый клик add new field тип lookup дальше интуитивно понятно.... только для справочников предварительно сделай датасеты...

Автор: Rowi 20.2.2006, 01:05
YurikGL, Огромное спасибо, получилось!!! Нечто подобное я уже делал раньше с TTable, но не знал, что используя SQL, можно делать так же...

Т.е. я добавил два доп. датасета (setWorkers и setCustomers), затем в основном датасете через FieldsEditor добавил подстановочные поля CustName и WorkerName (правда, сами связующие поля "КодКлиента" и "КодСотрудника" пришлось тоже включить и поставить Visible:= false, чтобы на глазах не маячили), а в CommandText основного датасета записал просто 'SELECT * FROM Заказы'.
И теперь всё чудненько и добавляет, и редактирует! smile

НО!!! Не получается сделать простейшую фильтрацию типа
'SELECT * FROM Заказы WHERE CustName = "Вася" ' : ругается, что "Отсутствует значение для одного или нескольких требуемых параметров." smile
Я, вообще-то догадываюсь, что он хочет не CustName (подстановочное поле), а "КодСотрудника", но ведь пользователь не видит (зачем ему голову забивать!) этот код! Он знает только ИМЯ сотрудника, и хочет найти все записи с этим именем!

Как тут быть? Ведь без элементарной (хотя бы) фильтрации зачем тогда SQL? Видимо, я что-то ещё не так делаю. Но что?

P.S. По дате фильтрует нормально

Автор: YurikGL 20.2.2006, 20:19
Ты хочешь отфильтровать записи и отфильтрованный список редактировать...
А как ты себе представляешь реакцию системы, если ты в отфильтрованном наборе WHERE CustName = "Вася" в поле CustName введешь "Петя"? По логике, запись должна будет исчезнуть т.к. она оказывается вне фильтра.

Кстати, можно еще попробовать заранее сделать запрос в Access и загружать его в программу, как обычную таблицу.

Автор: Rowi 21.2.2006, 23:01
Цитата(YurikGL @ 20.2.2006, 20:19 Найти цитируемый пост)
По логике, запись должна будет исчезнуть т.к. она оказывается вне фильтра

По логике - вроде да! А по опыту пользователя:
Цитата(YurikGL @ 20.2.2006, 20:19 Найти цитируемый пост)
Ты хочешь отфильтровать записи и отфильтрованный список редактировать...

Именно! А как же иначе! Ведь весь список может быть "о-го-го"! Как же пользователь найдёт этого самого "Васю", которого надо заменить на "Петю"? (Пардон за каламбур...)
Это наверняка можно (и нужно!) сделать, только, возможно, каким-то другим способом...

Автор: Rowi 22.2.2006, 10:41
Цитата(YurikGL @ 20.2.2006, 20:19 Найти цитируемый пост)
Кстати, можно еще попробовать заранее сделать запрос в Access и загружать его в программу, как обычную таблицу.

Пробовал. Результат тот же:
Цитата(Rowi @ 19.2.2006, 01:29 Найти цитируемый пост)
Т.е. они вроде вводятся и сохраняются(?), но при повторном применении того же запроса (для обновления данных) новых записей нет!
Проверяю через Access - в таблицах "Сотрудники" и "Клиенты" новые записи есть (правда, дублирует фамилию столько раз, сколько ей должно быть сопоставлено Заказов) , а в "Заказах" тоже новые записи есть, но поля "КодКлиента" и "КодСотрудника" пустые. Видимо поэтому новый запрос их и не видит?

К тому же такой запрос не получится изменять в программе "по ходу дела"...

Автор: sexton 22.2.2006, 11:08
А первичные ключи в таблицах прописаны?

Автор: Rowi 22.2.2006, 11:49
Я создавал эти таблицы в Access'е через мастера таблиц, так что он сам предложил сделать первичными ключами для каждой таблицы соответственно КодЗаказа, КодКлиента и КодСотрудника. Я и не отказывался...

Автор: sexton 22.2.2006, 14:10
ОК, а в ConnectionString доступ соответствующий даден? Может стоит представить обществу пример проекта на рассмотрение...

Автор: Rowi 22.2.2006, 23:37
Цитата(sexton @ 22.2.2006, 14:10 Найти цитируемый пост)
ОК, а в ConnectionString доступ соответствующий даден?

Установлено "Share Deny None"


Цитата(sexton @ 22.2.2006, 14:10 Найти цитируемый пост)
Может стоит представить обществу пример проекта на рассмотрение...

Дико извиняюсь, что не догадался сразу!
Цепляю к посту архив с исходниками и "тренировочной" базой...

Автор: YurikGL 25.2.2006, 18:52
Цитата(Rowi @ 21.2.2006, 23:01 Найти цитируемый пост)
Как же пользователь найдёт этого самого "Васю", которого надо заменить на "Петю"?


Сортировкой...
А потом, в ehGrid есть фишка, когда начинаешь набирать на клавиатуре "Петя" и курсор сам позиционируется на петю...

Автор: SergeBS 26.2.2006, 09:16
Rowi,
DelphiKingdom, там статья "Немного об использовании ADO...". Когда будет решена проблема с вписыванием ключевых полей (не должны они быть пустыми, post/requery!), тогда и запросы заработают. TEdit - поменять на лукапкомбобоксы, чтобы из выбранного "Петя" получать значение ключевого поля и его уже загонять в select. Иначе придется вначале по "Петя" находить его код и уже его впихивать в select - лишний гимор, плюс возможность ввода "ППетя" с нулевым результатом.
Если не сработает, то рекомендую проверить лукап - есть ли связка между полями справочников (где коды, а не "Пети").

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