Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.06.2009, 13:47   #1
White_Dove
 
Регистрация: 15.06.2009
Сообщений: 4
По умолчанию [ADO] Не могу разобраться с добавлениями записи

Есть процедура добавления свойств объектов в базу данных.
Когда вызываю при создании объектов, все работает. Стоит в одном месте кода вызвать два раза подряд, и MSAccess начинает ругаться на совпадающие значения индекса. Хотя ключ, он же индекс, инкрементируется при создании программно
Что не так?

Код:
Const 
 FN_X=1; FN_Y=2;
 ...

function CreateObjectIn(ds:TDataSet; tr:T3DObject):boolean;
begin try
 Result:=false;
 ds.Last;
 if ds.RecordCount=0 then ID:=0 else ID:=ds.Fields[0].AsInteger+1;
 ds.Insert;
 ds.Fields[0].AsInteger:=ID;
 ds.Fields[FN_X].AsFloat:=tr.Coords.x;
 ds.Fields[FN_Y].AsFloat:=tr.Coords.y;
...
 ds.Post;
 tr.SourceID:=ds.Tag; tr.ID:=ID;
 Result:=true;
except
 Result:=false;
end end;
Другая часть кода:
Код:
...                  
//предварительные операции с объектами TempObject1 и TempObject2  

 CreateObjectIn(CurrentDataSet,TempObject1);                
 CreateObjectIn(CurrentDataSet,TempObject2);
Во втором вызове доходит до второго Post'а и начинает ругаться на совпадающий индекс. Хотя он (ID, он же ds.Fields[0].AsInteger) ни коим боком не совпадает! (проверено в отладчике) Так в чем проблема?

Стоит снять требование на несовпадающие индексы через Access, проблема исчезает. Но в чем она состоит-то?
в первый раз мы получаем значение ID, допустим, 27, и пишем его в качестве индекса объекта в БД. Во второй раз мы читаем значение 27 и пишем значение 28. Должно катить, но не катит.

Последний раз редактировалось White_Dove; 15.06.2009 в 13:52.
White_Dove вне форума Ответить с цитированием
Старый 15.06.2009, 14:11   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Хм... А чего б не поставить тип поля СЧЕТЧИК и пусть сам Акцесс заботится об инкременте ключа?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 15.06.2009, 14:18   #3
White_Dove
 
Регистрация: 15.06.2009
Сообщений: 4
По умолчанию

Перефразируя классическое, код не мой, я просто с ним работаю.
Но т.к. автор кода недоступен, приходится разбираться

Желательно все-таки понять, как исправить ситуацию средствами ADO
Какого фига один вызов такой функции прокатывает, а второй - валится на ПОСТе?

Последний раз редактировалось White_Dove; 15.06.2009 в 14:20.
White_Dove вне форума Ответить с цитированием
Старый 15.06.2009, 14:31   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Тут только отладчик даст тебе четкие ответы. Я бы пошагам прошелся, и посмотрел чего там в ID пишется...
А вообще это не очень удачная тактика. Советую ее не использовать.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 15.06.2009, 14:42   #5
White_Dove
 
Регистрация: 15.06.2009
Сообщений: 4
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Тут только отладчик даст тебе четкие ответы. Я бы пошагам прошелся, и посмотрел чего там в ID пишется...
А вообще это не очень удачная тактика. Советую ее не использовать.
Отладчик именно и говорит то, что я написал в начале. Немножко поясню:
в первый раз мы получаем значение ID из последней записи БД(ID=26), и для новой формируемой записи используем значение 27. Именно это и показывает отладчик.
Во второй раз мы читаем значение 27 из последней записи (только что созданной) и используем значение 28. Перед самым вызовом поста значение ds.Fields[0].AsInteger во вновь формируемой записи=28! Жму F8, и БД выдает ошибку совпадающих индексов!

Переформулирую вопрос применительно к ADO:
Достаточно ли тех операторов, которые есть, чтобы применять эту функцию несколько раз подряд?
White_Dove вне форума Ответить с цитированием
Старый 15.06.2009, 14:58   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Можно глянуть на твою БД?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 15.06.2009, 20:30   #7
Gulik
Холост/Не замужем
Форумчанин
 
Аватар для Gulik
 
Регистрация: 13.11.2007
Сообщений: 283
По умолчанию

Код:
function CreateObjectIn(ds:TDataSet; tr:T3DObject):boolean;
begin
   Result:=false;
   ds.Append;
   ds.Fields[0].AsInteger:=ds.RecordCount; 
   ds.Fields[FN_X].AsFloat:=tr.Coords.x;
   ds.Fields[FN_Y].AsFloat:=tr.Coords.y;
   ...
   if ds.Modified then
      ds.Post;
   tr.SourceID:=ds.Tag;
   tr.ID:=ds.RecordCount;
   Result:=true;
end;
Но при удалении строки такой код заругается, если в Акцесе стоит на ID - провторения не допускаются

или попробуй в своем коде заменить ds.Insert; на ds.Append;

Последний раз редактировалось Gulik; 15.06.2009 в 20:36.
Gulik вне форума Ответить с цитированием
Старый 16.06.2009, 13:23   #8
White_Dove
 
Регистрация: 15.06.2009
Сообщений: 4
По умолчанию

Мне необходимо заменить один объект на два и, соответственно, заменить одну запись в БД на две.

Но тогда вопрос: Гулик, если для тебя вопрос ругани очевиден, можно поподробнее, в каком месте ругань? И как, и почему ты модернизировал мой код?
Меня ногами не пинать, я с ADO месяц как знаком. Но проблему решать надо.

На всякий случай: код удаления записи в программе следующий:

Код:
   ds.First;
   (ds as TADODataSet).Locate(Result.Fields[0].FieldName,elem.ID,[]);
   if ds.RecordCount>0 then ds.Delete;

Последний раз редактировалось White_Dove; 16.06.2009 в 14:03.
White_Dove вне форума Ответить с цитированием
Старый 16.06.2009, 17:53   #9
Gulik
Холост/Не замужем
Форумчанин
 
Аватар для Gulik
 
Регистрация: 13.11.2007
Сообщений: 283
По умолчанию

мое мнение:
Каждую новую запись тебе нужно добавлять в конец таблицы, делать это лучше с помощью Append а не переходить в конец таблицы, проверять её полноту записей а затем добавлять новую.

И тебе уже говорили что пусть сам Акцесс заботится об инкременте ключа
Gulik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Удаление записи. ADO Rekky БД в Delphi 13 02.11.2011 12:46
Как удалять записи по условию, через ADO Dimok82 БД в Delphi 4 13.03.2009 19:28
Удалить 2 записи. ADO... Roof БД в Delphi 9 18.08.2008 20:32
Отображение записи (работа с ADO) А. Долматов БД в Delphi 3 21.08.2007 16:58
MS SQL server 2000, ADO. Добавленые записи не отображаются при последующих запросах. _victor БД в Delphi 1 17.06.2007 13:33