ホーム
Top.Mail.Ru Yandeks.Metrika
フォーラム: "Bases";
現在のアーカイブ: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 全枝

フォーラム: "Bases";
現在のアーカイブ:2002.01.08;
ダウンロード:[xml.tar.bz2];

2階









メモリ:0.85 MB
時間:0.026 c
1-22076
ヘビ
2001-12-19 12:50
2002.01.08
BIOSのリリース日を調べる方法は?


14-22349
イワン・シハレフ
2001-11-06 21:48
2002.01.08
アナトリーポドゴレツキー


14-22352
マーリン
2001-11-02 13:04
2002.01.08
すべての動きを記録しました!!!


1-22129
アレクサンドル
2001-12-19 16:04
2002.01.08
スクロールバーのちらつきを取り除くには?


14-22393
フェリックス
2001-11-08 21:54
2002.01.08
何をしますか?





アフリカーンス語 アルバニア語 Arabic アルメニア語 アゼルバイジャン語 バスク ベラルーシ Bulgarian カタロニア語 中国語(簡体字) 中国語(繁体字) クロアチア チェコ語 デンマーク語 Dutch 英語 エストニア語 タガログ語 Finnish フランス語
ガリシア語 ジョージアン ドイツ語 ギリシャ語 ハイチ語 ヘブライ語 ヒンディー語 ハンガリー語 アイスランド語 Indonesian アイリッシュ イタリア語 日本語 Korean ラトビア語 リトアニア マケドニア語 Malay マルタ語 Norwegian
ペルシア語 ポリッシュ ポルトガル語 ルーマニア Russian セルビア Slovak スロベニア語 スペイン語 スワヒリ語 Swedish Thai トルコ語 ウクライナ語 ウルドゥー語 ベトナム語 ウェールズ語 イディッシュ語 ベンガル語 ボスニア語
セブアノ語 エスペラント グジャラート語 ハウサ語 モン族 イボ ジャワ語 カンナダ語 クメール語 ラオ語 ラテン マオリ語 マラーティー語 モンゴル語 ネパール語 パンジャブ語 ソマリ タミル語 テルグ語 ヨルバ語
ズールー語
Английский Французский Немецкий Итальянский ポルトガル語 Русский Испанский