Конференция "Базы" » Проблема при добавлении записи через ADO в mdb файл [D6]
 
  • leonidus © (21.05.12 10:44) [0]
    Для работы с БД использую ADO. Файл обычный аксесовский mdb.  В базе всего одна таблица из 4-х полей без автоинкрементного поля. Все поля текстовые. Первое поле (screen_name) индексное, совпадения запрещены, в остальных полях совпадения разрешены.

    Перед добавлением данных в таблицу делается проверка:

    if form1.ADODataSet1.Locate('screen_name',Acc,[])=false then
    begin //такого имени в базе нет - добавляем его
       try
        form1.ADODataSet1.Insert;
        form1.ADODataSet1['screen_name']:=Acc;
        form1.ADODataSet1.Post;
       except
       end;
    end;

    На всякий пожарный блок добавления данных в БД помещен в try/except.

    Периодически, пользователи сообщают о том, что в ходе записи в базу появляется сообщение "Изменения не были успешно внесены из-за повторяющихся значение в индексе". Не моуг понять как такео возможно. Во-первых я проверяю есть ли запись в базе прежде чем в нее пишу. Во-вторых подобную месагу должен задержать блок try/except. Получается что Locate отрабатывает не верно или что?
  • sniknik © (21.05.12 10:51) [1]
    при отсутствии ключевого поля в выборке/или при не указании использовать ключ для формирования запроса/или при не считывании значения ключа(автоинкремента) из базы в рекордсет, определение записи идет по всем возможным полям. + Locate ищет в локальной выборке, а указанная ошибка идет из базы.
    ++
    есть хорошие статьи про ADO на королевстве...
  • leonidus © (21.05.12 17:18) [2]
    sniknik я правильно понял, что нужно все же добавить автоинкрементное поле?

    На счет Locate. Не очень понял на счет локальной выборки. Перед началом работы с таблицей выполняется следующий код:
    form1.ADODataSet1.Active:=false;
    form1.ADODataSet1.CommandText:='SELECT * FROM '+TableName;
    form1.ADODataSet1.Open

    в итоге ADODataSet1 хранит всю таблицу.
  • sniknik © (21.05.12 17:56) [3]
    > что нужно все же добавить автоинкрементное поле?
    если хочешь по нему обновлять записи то обязательно.

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

    > в итоге ADODataSet1 хранит всю таблицу.
    программа одна работает? из другого источника записи быть не может?
    это раз.
  • sniknik © (21.05.12 18:04) [4]
    вот это посмотри - Update Criteria
    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=413
  • leonidus © (21.05.12 18:08) [5]
    Уточняю. Программа работает с БД монопольно, база на том же компе что и программа. Поэтому все же склоняюсь к тому, что один раз при коннекте с БД (при старте программы) загрузив в нее всю таблицу я обеспечиваю в дальнейшем Locate возможность искать по всей таблице а не по ее части. Другой вопрос. Если скажем при старте программы в базе было 100 записей и в ADODataSet1 загрузили их все, но в ходе работы записи то постепенно добавляются. Будет ли Locate искать все время по первым 100 записям или его поле поиска будет расширятсья вместе с ростом кол-ва записей?

    На счет оновление записей по автоинкрементному полю.

    Вот расширенние кода приведенного мной выше где видно что именно я обновляю если запись в БД уже имеется.

     if form1.ADODataSet1.Locate('screen_name',Acc,[])=false then
      begin //такого имени в базе нет - добавляем его
       try
        form1.ADODataSet1.Insert;
        form1.ADODataSet1['screen_name']:=Acc;
        form1.ADODataSet1['dt']:=DateTimeToUnixTime(Now);
        form1.ADODataSet1['id']:=UserID;
        form1.ADODataSet1['main_list']:='1';
        form1.ADODataSet1.Post;
       except
       end;
      end
       else
        begin  //имя в базе присутсвует - обновим запись
         form1.ADODataSet1.Edit;
         form1.ADODataSet1['dt']:=DateTimeToUnixTime(Now);
         form1.ADODataSet1['main_list']:='1';
         form1.ADODataSet1.Post;
        end;
  • sniknik © (21.05.12 19:45) [6]
    уточняю. или работаешь правильно, или смирись с ошибками, обвиняй во всем "этот глючный виндовс".

    > где видно что именно я обновляю если запись в БД уже имеется.
    еще из него видно, что описанная ошибка произойдет при нажатии на кнопку с этим кодом более 1 раза в секунду.
    если ты проигнорировал все ранее мной (в основном конечно ссылка, мои объяснения подозреваю не очень понятны) сказанное.
 
Конференция "Базы" » Проблема при добавлении записи через ADO в mdb файл [D6]
Есть новые Нет новых   [134430   +2][b:0][p:0]