Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Тут пролетал запрос, возвращающий


Страницы:   1 2 3

dtm ©   (2003-09-23 17:51:00) 

Уважаемые, напомните, плз. Вроде как его тут публиковал уважаемый Johnmen, но на тот момент я его скопировать не смог. Буду благодарен, если опубликуете его снова.


Zacho   (2003-09-24 21:37:00) [1]


> kaif © (24.09.03 21:10) [47]
> Ты это сам придумал или есть хорошая книга (статья) о примерах
> использования разных параметров транзакций IB?

Единственная известная мне хорошая и подробная статья о транзакциях в IB - http://www.ibase.ru/devinfo/ibtrans.htmПравда, примера именно для такого использования SNAPSHOT TABLE STABILITY с явным резервированием таблицы protected write там вроде бы нет (и вообще с примерами не густо), но именно этой статьей я и руководствовался, когда понадобилось сделать "бездырочную" нумерацию.


kaif   (2003-09-24 21:10:00) [2]

2 Zacho © (24.09.03 20:36) [46

Я уже как-то (и вроде даже не раз) приводил пример, как надо делать
Ни разу не читал об этом...
Век живи - век учись. Я никогда не использовал такие хитрые параметры транзакции...
consistency wait lock_write=<имя таблицы> exclusive
Мне это нравится. Конечно транзакция должна быть короткой. Но это как раз не проблема.
Ты это сам придумал или есть хорошая книга (статья) о примерах использования разных параметров транзакций IB? Я знал о существованиии режима wait lock write, но мне в голову не пришло использовать это для решения подобных задач с нумерацией...
Причем решение-то действительно классное!


Zacho   (2003-09-24 20:36:00) [3]


> kaif © (24.09.03 20:18) [44]

Не надо так делать. Я уже как-то (и вроде даже не раз) приводил пример, как надо делать. Если кратко, то получение следующего номера (SELECT MAX(..)+1) и вставка записи - в отдельной короткой транзакции c параметрами consistency wait lock_write=<имя таблицы> exclusive. И не надо будет никаких циклов и обработок нарушений ПК.


kaif   (2003-09-24 20:21:00) [4]

Пардон, в коде нужно в начале:
вместо NewN := QueryMaxN - 1
написать NewN := QueryMaxN + 1


kaif   (2003-09-24 20:18:00) [5]

2 alex_raider © (24.09.03 19:40) [41]
А генерировать новый ID не на OnNewRecord, а в триггере BeforeInsert самой БД нельзя?
Тогда даже если юзер и отменит транзакцию(вставку документа), то номер не сгенерится.


Боюсь, сгенерится. Генераторы IB работают вне контекста транзакции, а триггеры - в контексте.
Так что при откате транзакции дырка все равно будет.

Вопрос в другом. На фиг вообще операции нумеровать? Если же эти номера имеют какое-то философское значение, то их нельзяуже менять и дырки от удалений (если таковые законодательством не возбраняются) обязаны будутприсуствовать. Если же кому-то в международных организациях или налоговых инспекциях не нравятся дырки, то причину этого странного явления нужно искать при помощи психоанализа З.Фрейда в их глубоком детстве или в арбитражном суде.

Если же просто хочется уменьшитькол-во дырок, возникающих из-за отката транзакций по вставке, то можно сделать какой-нибудь банальный код типа:

NewN := QueryMaxN - 1; //функция, возвращающая максимальный номер
//SELECT MAX(N) FROM TABLE1

while True do
try
DataSet.Edit;
DataSet.FieldByName("N").AsInteger := NewN;
DataSet.Post; //тут может вылететь на нарушении ключа
Transaction.CommitRetaining; //тут на еще каком конфликте
break;
except
NewN := NewN + 1; //пробуем следующий номер
end;

И никаких генераторов.
Генераторы использовать только для суррогатных ключей типа ID. Нумерация "без дырок" к таким ключам не относится, хотя поле N должно иметь уникальный индекс, который вызовет исключительную ситуацию в приведенном коде.

Решение может не самое быстрое, но практически приемлемое, ИМХО.
Правда сам я пока никогда так не делал :)
Но как-нибудь попробую.


MsGuns   (2003-09-24 20:00:00) [6]

>dtm (24.09.03 18:28) [40]
Конечно, alex_raider © насчет неверной постановки всей задачи маненько загнул, но вот что действительно непонятно, так это твои попытки дергать генератор ДОвставки записи в таблицу (не путать с добавлением новой строки в грид).
Возможно, следует отказаться от редактирования данных в гриде, вынеся всю юзерскую активность в не DB-контролы в отд.панельке (или мод.форме), где и сделать кнопульки "Записать", "Отменить" и т.д. ?


alex_raider   (2003-09-24 19:41:00) [7]

так что постановку задачи нужно пересмотреть :-)


alex_raider   (2003-09-24 19:40:00) [8]

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

А генерировать новый ID не на OnNewRecord, а в триггере BeforeInsert самой БД нельзя?
Тогда даже если юзер и отменит транзакцию(вставку документа), то номер не сгенерится.

Если вставил документ, а он не нужен, то
"САМ ДУРАК", все шито-крыто.

Короче, хочу подытожить,
резюме:
"Шаманство" с получением максимального номера -
есть дурной тон и его нужно избегать. Ты автоматически налетаешь на проблему с блокировками и транзакционностью (т.е. не safe для многопользовательской системы) и никак ее не избежишь, кроме как блокировкой таблицы в момент SELECT`a.
Я решал подобную задачу 4 года назад, правду тебе говорю :-)))


dtm   (2003-09-24 18:28:00) [9]

Alex_Raider [32]
> У тебя сама постановка алгоритмики и способа решения неправильная.
>Следует сделать иначе - ничего не удалять,
а просто помечать записи(документы) как "удалено, недоступно, заблокировано".

;) Всё у меня правильно.
Пользователь вызывают новую операцию, она должна уже на этапе создания иметь уникальный номер - она его и имеет, получая от генератор. Если пользователь отменил во время оформления операцию - номер теряется, так как уже был сгенерирован. Естественно, что в базе ничего не остаётся, так что помечать "удалено, недоступно, заблокировано" просто нечего.
А есть ещё софтина, обрабатывающая информацию об операциях, поступающих из разных концов Беларуси, и по правилам ведения работы заказчика (а они определяются международной конвенцией) номера у документов должны быть по возможности последовательные, то есть без "дырок". Может, "дырки" всё равно будут, но для сертификации программы перед использованием я обязан вложить подобную функцию в программу. Иначе никак.
Так что не надо говорить, что кто-то поставил задачу неправильно...


Sandman25   (2003-09-24 16:12:00) [10]

:)


Alex_Raider   (2003-09-24 16:01:00) [11]

>>Вы принципиальный сторонник отказа от оптимизации? Если >>клиента что-то не устраивает, пуст покупает четвертый винт и >>пятый процессор?

Нет, я сторонник здравого смысла.
:-)


Johnmen   (2003-09-24 13:14:00) [12]

>MsGuns © (24.09.03 12:53)

Нет-нет-нет. Именно с теоретической. По-моему, "начальная дырка" это скорее всего "ближе к практике", если вообще тут можно о практике говорить... =o)


Sandman25   (2003-09-24 12:55:00) [13]

[34] Alex_Raider © (24.09.03 12:48)

Вы принципиальный сторонник отказа от оптимизации? Если клиента что-то не устраивает, пуст покупает четвертый винт и пятый процессор?


MsGuns   (2003-09-24 12:53:00) [14]

>Johnmen © (24.09.03 11:43) [31]
Ты же сам говоришь, что это вопрос скорее теоретический и тут же принимаешься критиковать "начальную" дырку с чисто практической т.зр.
;))
Если же иметь в виду "вакантность" UID, то не вижу никакой разницы, откуда его выбирать, т.е. будет это 1 или 1001 - нет для физической модели БД никакой разницыДругими словами, мне больше по душе итоговая последовательность

1,2,3,56,57,58,59,101,102

нежели

56,57,58,59,60,61,62,101,102

Чисто эстетически.


Alex_Raider   (2003-09-24 12:48:00) [15]

Каждому свое.
Извращайся до посинения,
если неспособен оценить трудоемкость/затраты решений.

А если хочешь экономить память и дисковое пространство - не используй версионники, C/S, и Windows вместе с Delphi.
Используй Zx Spectrum 48, все 49152 байта RAM твои...


Sandman25   (2003-09-24 12:31:00) [16]

>Следует сделать иначе - ничего не удалять,
а просто помечать записи(документы) как "удалено, недоступно, заблокировано".

Расходуется лишняя память, замедляется поиск и вставка записей.


Alex_Raider   (2003-09-24 12:10:00) [17]

У тебя сама постановка алгоритмики и способа решения неправильная.

Следует сделать иначе - ничего не удалять,
а просто помечать записи(документы) как "удалено, недоступно, заблокировано".

И никаких "дырок" бы не появилось.
Вот так-то.


Johnmen   (2003-09-24 11:43:00) [18]

Согласен с kaif ©, что рассматриваемый вопрос лежит не в плоскости практического применения, а с скорее в теоретической, не привязанной к реальным построениям систем.
А по поводу начальной дырки, так нет такого понятия. Поясню.
Есть интервал с дырками. Конечное значение интервала - максимальное значение ID. А вот минимальное почему же 0, или 1 ??? Вовсе нет. Минимальное - минимум ID. И никак иначе. В противном случае придем к нарушению понятия "дырки в интервале". По определению интервал не может начинаться с дырки.
Конечно можно считать минимумом 0 или 1. Но это уже искусственный частный случай.
И, конечно же, самое быстрое здесь это ХП.

(Не может быть, что я столько слов тут написал :))

>Sandman25 © (24.09.03 11:11)

Хороший запрос. И по идее, действительно, должен работать бастрее.
Посмотрел планы и того и другого. В общем, понятно, почему быстрее.


Val   (2003-09-24 11:40:00) [19]

>Danilka © (24.09.03 11:25) [29]
:) на самом деле это - интервалы


Danilka   (2003-09-24 11:25:00) [20]

Как говорил мне тесть "дыры, дырки и дырочки они у женщин, а это - отверстия".


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо