Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Вывод результата запроса в edit.


Автор: PaWeLL 16.11.2009, 10:16
Появился вопрос. Есть таблица personal_inf, в которой хранятся данные о работниках. У каждого есть идентфикатор w_id.
Есть форма добавления записей в таблицу. Нужно, чтобы при загрузке формы в поле "Номер сотрудника" выводилось первое незанятое значение w_id. Как такое реализовать?

Автор: Данкинг 16.11.2009, 11:15
Цитата(PaWeLL @  16.11.2009,  10:16 Найти цитируемый пост)
первое незанятое значение w_id. 

Если w_id уникален и идёт по порядку, то взять максимальное его значение (select max w_id from table) и прибавить 1.

Автор: PaWeLL 16.11.2009, 11:21
Цитата(Данкинг @ 16.11.2009,  11:15)
Цитата(PaWeLL @  16.11.2009,  10:16 Найти цитируемый пост)
первое незанятое значение w_id. 

Если w_id уникален и идёт по порядку, то взять максимальное его значение (select max w_id from table) и прибавить 1.

Это я уже обдумал. Но мне хочется посложнее. Допустим в результате удаления оказался свободен один id

0015
0016
0018
0019

Так вот, надо чтобы выводился не 0020, а первый свободный 0017.

Автор: Данкинг 16.11.2009, 11:38
Цитата(PaWeLL @  16.11.2009,  11:21 Найти цитируемый пост)
Так вот, надо чтобы выводился не 0020, а первый свободный 0017. 

Тогда в цикле проходить (только сколько это по времени займёт) и искать соседние строчки, разница w_id между которыми больше единицы.

Добавлено через 2 минуты и 42 секунды
Но только не знаю, зачем это практически может быть нужно. Если требуется уникальное поле-идентификатор сотрудника, так обычное автоинкрементное поле отлично для этого подойдёт.

Автор: PaWeLL 16.11.2009, 11:42
Цитата(Данкинг @ 16.11.2009,  11:38)
Цитата(PaWeLL @  16.11.2009,  11:21 Найти цитируемый пост)
Так вот, надо чтобы выводился не 0020, а первый свободный 0017. 

Тогда в цикле проходить (только сколько это по времени займёт) и искать соседние строчки, разница w_id между которыми больше единицы.



То есть очень сложно получается, не по моим навыкам?

Цитата

Но только не знаю, зачем это практически может быть нужно. Если требуется уникальное поле-идентификатор сотрудника, так обычное автоинкрементное поле отлично для этого подойдёт.


А подробнее можно про это? А то я пока нуб в этом деле. Да, кстати, забыл упомянуть. База данных - paradox.

Автор: Данкинг 16.11.2009, 11:54
Цитата(PaWeLL @  16.11.2009,  11:42 Найти цитируемый пост)
То есть очень сложно получается, не по моим навыкам?

Почему сложно? Просто по времени такой цикл будет работать долго - в зависимости, конечно, от числа записей в таблице.

Цитата(PaWeLL @  16.11.2009,  11:42 Найти цитируемый пост)
Да, кстати, забыл упомянуть. База данных - paradox.

Я про "Парадокс" ничего не знаю, никогда с ним не работал. Но вот в Access есть поле типа "счётчик", и значения в нём всегда уникальные, генерируемые самой СУБД. В FireBird есть генераторы для той же цели.

Автор: former 16.11.2009, 12:45
Цитата(Данкинг @  16.11.2009,  11:15 Найти цитируемый пост)
Если w_id уникален и идёт по порядку, то взять максимальное его значение (select max w_id from table) и прибавить 1. 


Данкинг, ну а как быть если номер мы этот получили, заполняем форму, а в этот момент еще куча пользователей добавило записей? Такой способ подходит только если номер присваивается в триггере или процедуре непосредственно при сохранении данных. В данном случае (если бы речь не шла про Paradox) нужно получать значение с помощью генератора.
PaWeLL, бросай Paradox. Технология бесперспективная. Лучше уж Access.

Цитата(PaWeLL @  16.11.2009,  11:42 Найти цитируемый пост)
То есть очень сложно получается, не по моим навыкам?

Не нужно мерить задачу по себе. Так ты мало чего добьешься.

Автор: Данкинг 16.11.2009, 13:05
Цитата(former @  16.11.2009,  12:45 Найти цитируемый пост)
Данкинг, ну а как быть если номер мы этот получили, заполняем форму, а в этот момент еще куча пользователей добавило записей?

Я об этом не подумал, я конкретную задачу решал.  smile Просто первое, что мне пришло в голову - моя БД по учёту DVD, в которой именно таким образом выбирается максимальный диск, и новый диск получает номер, соответственно, +1. Но для сетевой БД такое не подойдёт, разумеется.

Автор: Frees 16.11.2009, 13:44
Для сетевого варианта только Генератры (firebird) или их аналоги в других СУБД. только они гарантируют уникальность, а максимум или последнее значение в списке могут привести к коллизии номеров.

Добавлено через 1 минуту и 37 секунд
Цитата(PaWeLL @  16.11.2009,  14:42 Найти цитируемый пост)
База данных - paradox.

поменяй СУБД пока не поздно..намучаешься ты с парадоксам

Автор: PaWeLL 16.11.2009, 13:48
Цитата(Данкинг @ 16.11.2009,  13:05)
Цитата(former @  16.11.2009,  12:45 Найти цитируемый пост)
Данкинг, ну а как быть если номер мы этот получили, заполняем форму, а в этот момент еще куча пользователей добавило записей?

Я об этом не подумал, я конкретную задачу решал.  smile Просто первое, что мне пришло в голову - моя БД по учёту DVD, в которой именно таким образом выбирается максимальный диск, и новый диск получает номер, соответственно, +1. Но для сетевой БД такое не подойдёт, разумеется.

Ну у меня БД не сетевая, поэтому не страшно.

Добавлено через 1 минуту и 26 секунд
Цитата(Данкинг @ 16.11.2009,  11:54)
Цитата(PaWeLL @  16.11.2009,  11:42 Найти цитируемый пост)
То есть очень сложно получается, не по моим навыкам?

Почему сложно? Просто по времени такой цикл будет работать долго - в зависимости, конечно, от числа записей в таблице.

Можешь хотя бы намекнуть, как это должно выглядеть?

Добавлено через 8 минут и 43 секунды
Цитата(Frees @  16.11.2009,  13:44 Найти цитируемый пост)
Добавлено через 1 минуту и 37 секунд
Цитата(PaWeLL @  16.11.2009,  14:42 Найти цитируемый пост)
База данных - paradox.

поменяй СУБД пока не поздно..намучаешься ты с парадоксам 


Я бы может и поменял, на задание определено четко: Delphi+paradox.

Автор: Frees 16.11.2009, 13:57
Цитата(PaWeLL @  16.11.2009,  16:48 Найти цитируемый пост)
Можешь хотя бы намекнуть, как это должно выглядеть?

суть такова

Код

var 
  priorId: integer;
  nexId: integer;
....
Table1.First;
priorId := Table1.fieldByName('w_id').asinteger;
nexId :=  priorId + 1;
Table1.Next;
while not Table1.eof do
begin
  nexId :=  priorId + 1;
  if Table1.fieldByName('w_id').asinteger <> nexId then
    breac;
  priorId := Table1.fieldByName('w_id').asinteger;   
  Table1.Next;
end;

//nexId - следующий ид, с заполнением дырок


Добавлено @ 14:08
Цитата(PaWeLL @  16.11.2009,  16:48 Найти цитируемый пост)
Я бы может и поменял, на задание определено четко: Delphi+paradox.

меняй задание

Автор: Deniz 16.11.2009, 14:41
Можно и select'ом выбрать
Код
select min(t1.w_id) +1 as NewNum from personal_inf t1 
where not exists(select 1 from personal_inf t2 where (t2.w_id = (t1.w_id + 1)))
как-то так, только если записей нет, запрос тоже ничего не вернет.

Автор: PaWeLL 17.11.2009, 18:23
Всем спасибо. С вопросом разобрался.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)