Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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



Страницы: 1 вся ветка

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

Наверх





Память: 0.47 MB
Время: 0.116 c
4-22509
Karan
2001-11-08 12:50
2002.01.08
GetkeyboardState- Что делает?


14-22329
Dima-k17
2001-11-03 15:12
2002.01.08
Времена Delphi закончились?


1-22219
dimonf
2001-12-16 17:23
2002.01.08
Как сделать, чтобы Canvas прорисовывался при любых монипуляцих с окном


1-22167
Art
2001-12-15 20:56
2002.01.08
Такая вот задачка!!!


1-22192
Dreamer
2001-12-15 19:34
2002.01.08
Как из Time вытаскивать только секунды и переводить





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский