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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.03.2009, 19:29   #1
RammFan
Пользователь
 
Регистрация: 26.11.2006
Сообщений: 18
По умолчанию Проблема со значением поля-счетчика при удалении записи

Здравствуйте.

Пишу программу, позволяющую редактировать аксесовскую базу данных: просмотр, удаление, добавление записей. Индексное поле - id - тип Счетчик. Таблица простейшая: Фамилия, Имя, и ряд подобных полей. Столкнулся с обычной проблемой, о которой сразу и не задумался: при удалении записи нарушается последовательность индекса. То есть были строки 1, 2, 3, 4 с соответствующими значениями индекса: 1, 2, 3, 4, а при удалении 3 записи получается 1, 2, 4. Явление понятное и нормально ), но неприятное. Пытался менять значения индекса:

for i:=1 to DataModul.DataModule2.MainTable.Rec ordCount do
begin
DataModul.DataModule2.MainTable.Rec No:=i;
if Datamodul.DataModule2.MainTable.Fie ldValues['id']<>IntToStr(i) then
begin
Datamodul.DataModule2.MainTable.Fie ldValues['id']:=i;
end;
end;

но выдает ошибку: Dataset not in edit or insert mode.
Пробовал в самой базе поменять значения индекса, тоже говорит что невозможно это сделать.

Как вариант, делать индекс текстовый и при добавлении записи присваивать нужный номер, но, хотелось бы с этим не запариваться )).

Вот вопрос, как с этим бороться? Спасибо.
RammFan вне форума Ответить с цитированием
Старый 22.03.2009, 19:36   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Никак. Счетчик не позволяет менять значения вручную. Он обнуляется только при создании страницы.
А почему вас это смущает?
Заведите себе еще одно поле и нумеруйте в нем записи как вам заблагорассудится.
Но опять же - придется "париться" после каждого удаления.
Обычно поле-счетчик удобно использовать для организации ссылок между таблицами, а там не важно - подряд идут значения или нет.

Последний раз редактировалось mihali4; 22.03.2009 в 19:56.
mihali4 вне форума Ответить с цитированием
Старый 22.03.2009, 19:43   #3
RammFan
Пользователь
 
Регистрация: 26.11.2006
Сообщений: 18
По умолчанию

В принципе, это не столь важно, просто я немного не правильно считывал записи из таблицы, это мне сейчас вдруг в голову пришло )))))

Спасибо.
RammFan вне форума Ответить с цитированием
Старый 28.03.2009, 05:40   #4
Vova20years
Пользователь
 
Регистрация: 27.03.2009
Сообщений: 12
По умолчанию

ну а все-таки, меня тоже эта проблема интересует!! как это можно обойти?
у меня аналогичная задачка, я поле id сделал числовым и при добавлении записи выискиваю max id и прибавляю : mах+1 вроде такое работает, а вот что делать при удалении?? очень надеюсь на совет!!
Vova20years вне форума Ответить с цитированием
Старый 28.03.2009, 10:19   #5
Антон Ю.Б.
Форумчанин
 
Регистрация: 03.01.2009
Сообщений: 116
По умолчанию

Если речь идет об Access, то по идее можно попробовать так:
1) delete FROM Таблица1 where Код=RC;
2) update Таблица1 set Код=Код-1 where Код>RC; (при этом в таблицах, для которых Код Таблицы1 - внешний ключ произойдет каскадное обновление)
3) программно инициировать сжатие БД Access

P.S. Если бы речь шла о таблице, на которую нет ссылок, то можно было бы вместо 3) произвести удаление и повторное создание поля счетчика
P.P.S. Если бы речь шла не об Access, то в качестве 3) достаточно было бы программно изменить значение генератора, используемого полем-счетчиком.
P.P.P.S. Сама постановка задачи все же несколько отдает абсурдом. Опять же, если бы речь шла не об Access, то почти наверняка можно было в запросе, получающем отображаемые данные, сделать счетчик выбранных строк.
Антон Ю.Б. вне форума Ответить с цитированием
Старый 28.03.2009, 12:31   #6
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

Цитата:
Сообщение от Vova20years Посмотреть сообщение
у меня аналогичная задачка, я поле id сделал числовым и при добавлении записи выискиваю max id и прибавляю : mах+1 вроде такое работает
раз уж речь про БД, то такой подход при многопользовательской БД будет причиной кучи гемора с дедлоками (если речь идет про праймари на таблицу)
если поле не основное, то никаких проблем
soleil@mmc вне форума Ответить с цитированием
Старый 28.03.2009, 18:15   #7
Vova20years
Пользователь
 
Регистрация: 27.03.2009
Сообщений: 12
По умолчанию

Антон Ю.Б. я решил пойти по твоему первому совету--удаляю запись и заново генерирую счетчик!! но у меня не получается! вот код подскажите ребята в чем моя ошибка:

Код:
procedure TForm1.Button2Click(Sender: TObject);
var i,n: integer;
begin
adobase.delete;
n :=  adobase.recordcount;

adobase.edit;
adobase.first;

for i:=1 to n do  begin
adobase.FieldValues['№_poryadkoviy'] := inttostr(i);
adobase.Next;
end;
adobase.Post;

end;
заранее спасибо!!
p.s. у меня это первая БД, я темы просматривал но подробно про такую казалось бы легкую проблемку нигде не написано!!
Vova20years вне форума Ответить с цитированием
Старый 29.03.2009, 11:04   #8
Антон Ю.Б.
Форумчанин
 
Регистрация: 03.01.2009
Сообщений: 116
По умолчанию

Vova20years, там решение (и это второй, а не первый вариант) состояло в том, что поле удаляется вовсе из таблицы. Для этого надо в общем случае а) получить имя индекса (метод GetIndexNames компонента-набора данных: TTable и т.д.) б) удалить индекс SQL запросом в) удалить поле SQL запросом г) создать поле вновь д) создать индекс вновь.

P.S. Разумеется, перед всем этим надо закрыть все наборы данных, связанные с этой таблицей.

И еще - ну что значит "легкая проблемка"? Вы выдумали себе задачу, которая не предусмотрена самой парадигмой реляционных СУБД. Такая задачка может возникать (и то - очень спорно) только из потребностей клиента (интерфейса), ну так и решать ее надо на уровне представления (отображения) данных, а не на уровне их хранения. Как это сделать в Access - не знаю, вот пример в Firebird, где для этого нет стандартных средств (http://www.firebirdsql.su/doku.php?id=rdb_get_context), во многих СУБД есть и стандартные средства для такого.

Последний раз редактировалось Антон Ю.Б.; 29.03.2009 в 11:12.
Антон Ю.Б. вне форума Ответить с цитированием
Старый 29.03.2009, 11:53   #9
Vova20years
Пользователь
 
Регистрация: 27.03.2009
Сообщений: 12
По умолчанию

У меня простенькая бд--каждый месяц к нам приходит какое-то кол-во продукции(100,300 и т.д--это не так важно)). я ее заношу в одну базу, бд у меня локальная, вот мне и нужно знать общее кол-во записей, ведь при удалении если поле выставлено в access как счетчик то эта запись удаляется а остальные не перерасчитает.
как видите, все вполне обоснованно!

все, решил этот вопрос-после удаления записи выполняй перерасчет поля-счетчика
Код:
procedure TForm1.Button2Click(Sender: TObject);
var i,n: integer;
begin
i:=1;
adobase.delete;
adobase.first;
while not adobase.Eof do  begin
adobase.edit;
adobase.fields[0].asinteger := i;
i := i+1;
adobase.post;
adobase.Next;
end;

Последний раз редактировалось Vova20years; 29.03.2009 в 12:54.
Vova20years вне форума Ответить с цитированием
Старый 29.03.2009, 12:54   #10
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Ну количество записей-то вы всегда можете посмотреть - это Datamodul.DataModule2.MainTable.Rec ordCount...
mihali4 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Уменьшение счетчика в записи azat20 Общие вопросы C/C++ 1 22.02.2009 22:03
Как вывести сообщение типа "внимание" при удалении записи из БД Alex_Sokolov Помощь студентам 7 06.01.2009 13:50
Ошибка при удалении... JRcoker Общие вопросы Delphi 8 29.07.2008 22:53
Проблемы при удалении файлов Pavel55 Общие вопросы Delphi 7 10.01.2008 00:45