Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Вниз

Определить первый свободный ID 


S_King   (2001-12-04 10:18) [0]

Мастера помогите как определить в хранимой процедуре 1-й свободный №? Имеем таблицу с заполненым полем (1,2,4,5...),т.е. процедура должна выдать 3.



Vadim   (2001-12-04 10:51) [1]

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



Владислав   (2001-12-04 10:57) [2]

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

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



Yuvich   (2001-12-04 16:11) [3]

Если задача стоит именно так, то чтобы исключить ситуацию, описанную Владиславом ("Представь, что получиться, если два пользователя будут одновременно получать такой номер."), надо применить то что предлагает Vadim ("при помощи вспомогательной таблицы").

Вспомогательная таблица ведет список "дыр" в номерах. Как дыра образовалась - ее вставили в эту таблицу; как нужно заполнить дыру - прочитали из этой таблицы минимальный номер и удалили этот номер из этой таблицы. Все делается в триггерах и при блокировках "таблицы дыр", поэтому два пользователя никогда не прочитают один номер. Если используется метод исчисления, то нужно блокировать всю "целевую таблицу" - а это плохо для других пользователей, которые могут просто читать данные.



S_King   (2001-12-04 16:43) [4]

Все это понятно, но может быть можно прокрутить цикл
от 1 до max(Id) в хран. процедуре?

P/S: Извените, может быть плохо формулирую вопрос.



Vadim   (2001-12-04 16:52) [5]

Можно, но есть "но": при этом не гарантируется, что два пользователя одновременно не начнут "крутить цикл" и не наткнутся на одну и ту же "дыру" (я лично такую вероятность оцениваю как очень высокую). Если по условию задачи это допустимо - в путь, если нет, см. выше.



dmitryK   (2001-12-04 17:12) [6]

Если пользуешься SQL сервером, то логично решать такие задачи SQL-запросом, т.е. примерно так

select min(t1.ID)+1
from tabX t1 left join tabX t2 on t1.ID=t2.ID+1
where where t2.ID is NULL

будет работать все-таки быстрее чем программный перебор. А еще можно это реализовать с помощью журнала удаленных записей. Вешаешь триггер на удаление записи (бефоре) и сохраняешь все ID удаленных записей в отдельную таблицу. В таком случае при добавлении новых записей фактически нет потери времени на поиск (критично при одновременном добавлении большого количества записей). А что бы два пользователя не захватывали один ID поиск и добавление записи произодишь в одной транзакции.



S_King   (2001-12-05 09:55) [7]

Извените ребят, но я же не спрашивал про нескольких пользователей...
Но как все таки сделать цикл для одной таблицы



dmitryK   (2001-12-05 10:49) [8]

Что-то теперь я не понимаю, ты спрашивал как найти минимальный свободный ID. Я тебе привел запрос как это сделать. Зачем, спрашивается, тебе еще и цикл организовывать????



S_King   (2001-12-05 11:21) [9]

Я, что то не понял текста запроса, можно ли его создать для одной и той же таблицы?



dmitryK   (2001-12-05 12:33) [10]

select min(t1.ID)+1
from tabX t1 left join tabX t2 on t1.ID=t2.ID+1
where where t2.ID is NULL

tabX - это и есть твоя таблица. Она объединяется сама с собой. В результате получаешь запрос, который включает две колонки с ID
первая - все ID имеющиеся в твоей таблице,
вторая - если ID+1 есть, то ее значение, если нет, то NULL

where where t2.ID is NULL - оставляет только те где вторая колонка NULL, т.е. ID+1 свободно.

min(t1.ID)+1 - возращает минимальный номер свободного ID.

Подробнее читай описание языка SQL.

У такого запроса только один недостаток, должна быть хотябы одна запись в таблице, и номер свободного ID будет всегда больше минимального занятого.
Но это уже другая история...



S_King   (2001-12-05 16:32) [11]

Не знаю почему, но у меня этот запрос вешает базу насмерть.
пробовал в consol, expert




Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.031 c
14-22407          KL                    2001-11-03 00:47  2002.01.08  
Бета тестинг!!!


6-22287           Андрей                2001-08-08 10:35  2002.01.08  
Кто нибудь работал с WebSnap ????


4-22506           gluka                 2001-11-06 00:16  2002.01.08  
Как запихнуть *.dll-ку в ехе файл?


4-22456           RedMax                2001-11-01 11:10  2002.01.08  
COM объекты NetMeeting


14-22333          Nikolay               2001-11-03 20:12  2002.01.08  
$$$$$$$$$$$$$$$$$$$$$$$$$$