Работа с Access через ODBC.
На Аccess-е написана небольшая БД (таблиц десять, иерархия типа [главный]-[подчиненный|главный]-[подчиненный]) Программа подключает эту MDB-шку через BDE (настроен ODBC под мdb c алиасом).
_:(_Проблема:
При попытке добавить или как-то изменить данные полей(на форме используются DBEdit и DBComboBox) выдает ошибку "Non-blob column in table required to perform operation" - типа попытка не-blob запихнуть в blob.
Просьба, если кто уже сталкивался с подобными делами подсказать в чем суть. Заранее спасибо.
Если кому интересно, гляньте здесь
Уточню свою проблему...
Например есть:
таблица А - список сотрудников фирмы,
таблица В - список машин сотрудников,
таблица С - список вид машин.
Так вот, в С хранится список всех известных марок машин(поля: [№ в С], марка, ...), в В - список машин для определенного сотрудника (поля: [№ в В], [№ в С], ...).
В Acceess-е все работает на ура.
В Билдере настроиваю Tablе-ы как обычно (в поле MasterSource_А указываю DataSource_В и соответственно MasterFields поле, также и для связи В с С). При отображении таблиц через DBGrid все прекрасно смотрится, каждому полю А соответствует свое поле в В и также каждому в В - свое в С.
НО ошибка выходит при попытке создать нового сотрудника - т.е. при Table_A->Append()
Как правильно организовать эту систему, подскажите.
ЕСТЬ один вариант, но прошу меня поправить если что.
Может и не так, но мне кажется(надо бы где-то почитать об этом), что (возвращаясь к предыдущему примеру) нельзя добавлять непосредствено в таблицу А, к которой привязаны другие таблицы(в частности В).
Есть вариант создать другой экземпляр TTable этой же реальной таблицы А и править ее, а ссылочные поля из таблиц В и С брать из таких же других экземпляров TTable В и С.
Это конечно муторное дело(если в базе таблиц за 10), но кажется других вариантов нет.
Буду искать.
Как правильно организовать эту систему, подскажите.
:-? С таким не встречался.
Отключи (удали :)) DBgrid2 и DBGrid3, и так попробуй добавить новую запись. Если та же самая ошибка, то проблема не в мастер-детаил.
Можно еще отключить и DBComboBox(типа DataSource=NULL). Т.е. упростить форму до тех пор пока не заработает. А потом снова добавлять нужные элементы. Таким образом наверно можно будет определить причину ошибки.
Я что-то не припомню, чтобы записи так добавлялись.
обычно делаем так:
Table_A->Insert();
Table_A->Fields->FieldByName("FDate")->Value=(int)Date();
...
Table_A->Post();
Некоторые поля нужно устанавливать с осторожностью - вдруг установлены какие-то ограничения на значения (уникальность, автоинкремент, диапазон значений)
а еще лучше выполнить SQL запрос на добавление записи.
И лучше использовать "позднее связывание" - таблицы начинают звисеть друг от друга только в твоей программе (на уровне ассесс они как-бы ничего друг о друге не знают)
:) Сам себе..
ЕСТЬ один вариант, но прошу меня поправить если что.
Может и не так, но мне кажется(надо бы где-то почитать об этом), что (возвращаясь к предыдущему примеру) нельзя добавлять непосредствено в таблицу А, к которой привязаны другие таблицы(в частности В).
Есть вариант создать другой экземпляр TTable этой же реальной таблицы А и править ее, а ссылочные поля из таблиц В и С брать из таких же других экземпляров TTable В и С.
Это конечно муторное дело(если в базе таблиц за 10), но кажется других вариантов нет.
Буду искать.
Можно отключить Relation перед Insert в таблицу А, а затем снова их включить.
:-? С таким не встречался.
Отключи (удали :)) DBgrid2 и DBGrid3, и так попробуй добавить новую запись. Если та же самая ошибка, то проблема не в мастер-детаил.
Можно еще отключить и DBComboBox(типа DataSource=NULL). Т.е. упростить форму до тех пор пока не заработает. А потом снова добавлять нужные элементы. Таким образом наверно можно будет определить причину ошибки.
Спасибо за совет.
Попробовал запустить с только компонентами TTable, TDataSource и TDataBase. Форма чистая.
Выходит все равно сообщение оь ошибке.
Скорее всего дело в привязках таблиц.
Все больше склоняюсь к тому, что придется создавать копии TTable-s для добавления.
Можно отключить Relation перед Insert в таблицу А, а затем снова их включить.
если можно подскажи, а где найти этот Relation? Это свойство какого класса или компонента?
...
И лучше использовать "позднее связывание" - таблицы начинают звисеть друг от друга только в твоей программе (на уровне ассесс они как-бы ничего друг о друге не знают)
ART_CODE, объясни, а как используется "позднее связывание"?
если можно подскажи, а где найти этот Relation? Это свойство какого класса или компонента?
MasterField и MasterTable задает Relation.
MasterField и MasterTable задает Relation.
Извини, а не мог бы ты на кратком примере показать как
:)
типа того....
Table_A_Query->ExecSQL();
Взаимная зависимость таблиц может устанавливаться как минимум 2 способами :
1 - средствами БД Access
2 - твоей программой в о время выполнения. - это и есть - "позднее связывание" все то - же самое, что ты уже сделал ( указал MasterFields и т.п. )
Для чистоты эксперимента в самом Access эти связи должны отсутствовать (см. способ 1)
А SQL проходит или нет ?
типа того....
Table_A_Query->ExecSQL();
Как ты пишешь, SQL проводится и запись добавляется успешно.
Взаимная зависимость таблиц может устанавливаться как минимум 2 способами :
1 - средствами БД Access
2 - твоей программой в о время выполнения. - это и есть - "позднее связывание" все то - же самое, что ты уже сделал ( указал MasterFields и т.п. )
Для чистоты эксперимента в самом Access эти связи должны отсутствовать (см. способ 1)
Для чистоты связи в Acceess удалил. Однако попытка билдер-средствами добавить запись в таблицу приводит опять к ошибке.
Мне все больше кажется, что в когда таблицы в Билдере связаны по типу мастер-подчиненный(т.е. поля из одной подставляются автоматически в другую по соответствию ключевых полей) нельзя делать ТАБЛ_МАСТЕР->Insert().
Очень хочется чтоб я был не прав.:(
Мне все больше кажется, что в когда таблицы в Билдере связаны по типу мастер-подчиненный(т.е. поля из одной подставляются автоматически в другую по соответствию ключевых полей) нельзя делать ТАБЛ_МАСТЕР->Insert().
Очень хочется чтоб я был не прав.:(
Я не знаю, не проверял ( всегда использую только SQL).
Чем этот метод не устраивает ?
Закроешь таблицу, выплнишь SQL, снова откроешь таблицу....
Или программно временно разорвать связи таблиц, сделать Insert() , а затем все восстановить...
(здесь это уже предлогали... под туманным названием "Relation" :)) )
Я не знаю, не проверял ( всегда использую только SQL).
Чем этот метод не устраивает ?
Закроешь таблицу, выплнишь SQL, снова откроешь таблицу....
Или программно временно разорвать связи таблиц, сделать Insert() , а затем все восстановить...
(здесь это уже предлогали... под туманным названием "Relation" :)) )
Против SQL в принципе ничего не имею. Даже ЗА.
Скорее всего придется делать так как получается - через SQL query.
Если у кого будут еще какие-нибудь мысли, будет очень интересно узнать и применить.
А так, огромное спасибо
ART-CODE, AlexandrVSmirno и rostyslav за участие.