C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Нужна помощь по TADODataDriverEh + TMemTableEh
Valdemar
Отправлено: 27.12.2005, 13:45


Мастер участка

Группа: Участник
Сообщений: 433



Решил попробовать использовать TADODataDriverEh + TMemTableEh для работы с БД MS Access (EhLib 4.0.9b2 найденная в Интернете).
Для ADODataDriverEh в его же редакторе, вызываемом двойным кликом, написал запрос для Select и сгенерировал запросы для Update, Delete, Insert и GetRec.
SelectSQL
CODE
SELECT
user_id,
user_name,
login,
password,
is_admin
FROM users

InsertSQL
CODE
insert into users
 (user_name, login, password, is_admin)
values
 (:user_name, :login, :password, :is_admin)

UpdateSQL
SQL
update users
set
user_name = :user_name,
login = :login,
password = :password,
is_admin = :is_admin where user_id = :OLD_user_id

DeleteSQL
SQL
delete from users where user_id = :OLD_user_id

GetRecSQL
SQL
SELECT
user_id,
user_name,
login,
password,
is_admin FROM users WHERE user_id = :OLD_user_id

Данные в DBGridEh отображаются. Но при попытке добавления или изменения записи выдается сообщение об ошибке "Ошибка синтаксиса в инструкции INSERT INTO" или "Ошибка синтаксиса в инструкции UPDATE".
Может я чего-то забыл сделать или сделал не так?
В запросах типы параметров я задал, а их значения нигде не задавал.
Guest
Отправлено: 27.12.2005, 13:56


Не зарегистрирован







А delete и getrec работают?
Valdemar
Отправлено: 27.12.2005, 15:07


Мастер участка

Группа: Участник
Сообщений: 433



delete работает, а getrec нет (проверял вызывая MemTableEh->RefreshRecord())
olegenty
Отправлено: 27.12.2005, 15:07


Ветеран

Группа: Модератор
Сообщений: 2412



для Update должно быть так:
SQL
update users
set
user_name = :user_name,
login = :login,
password = :password,
is_admin = :is_admin where user_id = :user_id

постфикс "_OLD" не нужен. имя параметра должно быть идентично имени поля в случае, когда параметр должен заполняться значением поля существующей записи. (на самом деле имена могут быть любыми, но тогда никакой автоматики, всё руками)
кроме того, возможно, придётся заключить в квадратные скобки имена таблицы и полей.
а запрос тестировался средствами самого Access??? и что он говорит, при выполнении из Access?
Valdemar
Отправлено: 27.12.2005, 15:48


Мастер участка

Группа: Участник
Сообщений: 433



Префиксы OLD_ поставились автоматически при генерации запросов. Когда я сам писал все запросы, то имена параметров совпадали с именами полей, но результат был тот же, выдавалась ошибка синтаксиса.
Проверил запрос на Update в Access, задав вместо параметров конкретные значения. Запрос выполнился успешно.
olegenty
Отправлено: 27.12.2005, 15:55


Ветеран

Группа: Модератор
Сообщений: 2412



коллекция Parameters у UpdateCommand заполнена? если нет — вперёд.
Valdemar
Отправлено: 27.12.2005, 16:01


Мастер участка

Группа: Участник
Сообщений: 433



Да, у UpdateCommand созданы параметры (user_name, login, password, is_admin, user_id). Для параметров я указал тип, но значения не задаю.
olegenty
Отправлено: 27.12.2005, 16:26


Ветеран

Группа: Модератор
Сообщений: 2412



какой задан тип CommandType у UpdateComand?
у меня начинают кончаться рецепты. (но верно одно — что-то ты делаешь неверно, поскольку я работаю только посредством этих компонентов, и кроме счастья ничего не имею).
Valdemar
Отправлено: 27.12.2005, 16:30


Мастер участка

Группа: Участник
Сообщений: 433



у UpdateComand CommandType=cthUpdateQuery
Сейчас пробую то же самое сделать с использованием IBXDataDriverEh и базой FireBird. Может получиться.
olegenty
Отправлено: 27.12.2005, 16:33


Ветеран

Группа: Модератор
Сообщений: 2412



разницы никакой нет, что ADO, что IBX — внутри код TXXXDataDriverEh почти идентичен, разница лишь в именах фоновых компонентов и особенностях работы с ними.
Valdemar
Отправлено: 27.12.2005, 16:36


Мастер участка

Группа: Участник
Сообщений: 433



с использованием IBXDataDriverEh и базой FireBird все работает прекрасно
olegenty
Отправлено: 27.12.2005, 16:39


Ветеран

Группа: Модератор
Сообщений: 2412



значит надо было для ACCESS в квадратные скобки поля заключать.
Valdemar
Отправлено: 27.12.2005, 16:51


Мастер участка

Группа: Участник
Сообщений: 433



Да, действительно для Access имена полей надо заключать в квадратные скобки.
Все заработало.
olegenty, большое спасибо за помощь
Valdemar
Отправлено: 03.02.2006, 10:33


Мастер участка

Группа: Участник
Сообщений: 433



Возникла еще одна проблема. Сделал связку двух наборов данных по типу Master-Detail. Для подчиненного TMemTableEh задал MaserSource, MasterFields, DetailFields, и все запросы для TADODataDriverEh . В запросе SELECT в разделе WHERE задал поле, по которому идет связка.
Если MasterDetailSide равен mdsOnProviderEh, то при попытке вставить новую запись в подчиненную таблилицу выдается сообщение об ошибке, из которого понятно, что параметр, который должен содержать значение поля, по которому таблицы связаны, имеет значение NULL. При MasterDetailSide равном mdsOnSelfEh такой ошибки нет.
Вот запросы из компонентов TADODataDriverEh:
Для Master
запрос SELECT
SQL
SELECT line_id, line_name FROM lines

Для Detail
запрос SELECT при MasterDetailSide равном mdsOnSelfEh
SQL
SELECT prog_id, line_id, prog_name, shema, date_create, date_modify, user_id
FROM prog

запрос SELECT при MasterDetailSide равном mdsOnProviderEh
SQL
SELECT prog_id, line_id, prog_name, shema, date_create, date_modify, user_id
FROM prog WHERE line_id=:line_id

запрос INSERT
SQL
INSERT INTO prog ([line_id], [prog_name], [shema], [date_create],
[date_modify], [user_id])
VALUES(:line_id, :prog_name, '', Date(), Date(), :user_id)


В запросе INSERT параметр :user_id я хотел задавать самостоятельно. Делал это так ADODataDriverEh->InsertCommand->GetParams()->ParamByName("user_id")->Value=user_id;
Но не работает, ошибки нет но и значение параметра не задается. Когда значение параметра я задавал на этапе проектирования формы, то значение вроде бы есть, но при выполнении запроса INSERT вставляется значение NULL.
Подскажите, в чем может быть проблема. Или сделайте простейший проект, в котором реализована связка Master-Detail с возможностью вставки в подчиненную таблицу при MasterDetailSide равном mdsOnProviderEh.
И как программно задать значение параметра чтобы оно правильно вставлялось в таблицу?
olegenty
Отправлено: 03.02.2006, 11:01


Ветеран

Группа: Модератор
Сообщений: 2412



пример писать не буду, а вот как с этим справиться подскажу. есть таке событие у TADODataDriverEh: OnAssignCommandParameter. да, я тоже не большой любитель событий, но обработка этого события решит все твои проблемы. всё что нужно, это проверить, та ли команда выполняется, и если та, то проверить наименование параметра и руками задать значение тех параметров, которые не берутся из набора данных. и не забыть, для остальных параметров, вызвать DefaultAssignCommandParameter.
CODE

void __fastcall TForm1::ADODataDriverEh1AssignCommandParameter(
     TCustomSQLCommandEh *Command, TMemoryRecordEh *MemRecord,
     TDataValueVersionEh DataValueVersion, TParameter *Parameter)
{
   if (Command == ADODataDriverEh1->InsertCommand && AnsiString(Parameter->Name) == AnsiString("user_id"))
   {
       Parameter->Value = <твоё значение, которые ты знаешь, откуда взять>;
   } else
   {
       ADODataDriverEh1->DefaultAssignComandParameter((TADOCOmmandEh*)Command, MemRecord, DataValueVersion, Parameter);
   }
}


про MasterDetail не скажу, я эту связь организовываю руками (через таймер), и, соответственно, проблем не имею. однако, простой способ решения проблемы — обработка события OnNewRecord детальной таблицы и заполнение в нём мастерного поля (поскольку у меня связь мастер-деталь не явная, я пользуюсь именно им).

Отредактировано olegenty — 03/02/2006, 12:02

Вернуться в Работа с базами данных в C++Builder