Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизАвтоматическая номерация документов Найти похожие ветки
← →
Ярослав (2005-05-31 08:21) [0]Подскажите как автоматически назначать номера документов, т.е. записям БД. Они могут состоять как только из цифр, так и смешанные, т.е. буквенно цифровые, но это не есть особая проблемма, как сделать так чтобы они были уникальные и монотонно возрастающие.
Например когда два пользователя одновременно создают записи в одной таблице, чтобы им не назначилось одинакового номера. И если один из пользователей создовал документ и передумал, а номер документу был уже назначен, то другому пользователю был бы назначен это номер, т.е. небыло разрывов в нумерации.
Может есть какие нибудь статейки по этому поводу, поделитесь ссылками.
← →
Danilka © (2005-05-31 08:40) [1]Самый простой способ - формировать номер триггером, в момент записи документа в базу.
← →
Тучудище (2005-05-31 08:48) [2]Имхо на счет разрывов нумерации проблема актуальная по сей день...
← →
DenK_vrtz © (2005-05-31 09:04) [3]>на счет разрывов нумерации проблема актуальная по сей день...
эта проблема уже давно решена, но каждый решает ее своим способом :)
← →
Anatoly Podgoretsky © (2005-05-31 09:07) [4]Что бы не было разрывов в нумерации надо запретить изменение и удаление.
← →
Ярослав (2005-05-31 09:17) [5]Danilka © (31.05.05 08:40) [1]
А два триггера не могут одновременно сработать?
>> DenK_vrtz © (31.05.05 09:04) [3]
А можно поинтересоваться как...
Anatoly Podgoretsky © (31.05.05 09:07) [4]
Ну с запретом на удаление то все ясно, а изменение то зачем запрещать?
В том то и дело, что готовые документы удалять нельзя, и их номера другим присваевать, но вот если пользователь ошибочно чтото ввел и тут же удалил, пока документов с большим номером ни кто не сделал. Выбрать тот же номер для нового документа нет проблемм, но здесь как раз меня и интересует именно одновременное внесение записей в таблицу, могут ли например два триггера одновременно сработать?
← →
msguns © (2005-05-31 09:17) [6]№ документа состоит из 2-х частей: числовая и символьная.
Числовой № получается автоинкрементом, символьная часть вводится ручками.
Для униакльности создается индекс
Числовой номер "вытягивается с сервера на клиент, но может корректиться юзером перед вставкой. Вариант Danilka © (31.05.05 08:40) [1] не советую категорически, т.к. юзер не видит № при добавлении документа, а сие не есть гуд (очередной холивар ?)
← →
Anatoly Podgoretsky © (2005-05-31 09:22) [7]Ярослав (31.05.05 09:17) [5]
Имеется ввиду изменение номера, если мы имеем его, то имеем и дыру, кроме этого еще имеем и подделку.
← →
Ярослав (2005-05-31 09:28) [8]msguns © (31.05.05 09:17) [6]
Это все хорошо, но веть тогда о монотонности можно забыть ведь автоинкремент будет всегда новый, а она монотонность нужна бывает, иначе бы я о ней и не спрашивал, например номера приказов на предприятии как правило по порядку идут, да и много других таких документов.
А то что не видно номера в момент добавления так это не беда, в MS SQL его и так не видно... Да и ползователь готовя документ не знает о его будующем номере, да как правило и не надо ему его знать.
Но меня интересует могут ли одновременно сработать на сервере две ХП или триггера и назначить одинаковые номера?
← →
Sergey13 © (2005-05-31 09:28) [9]А по мне так вариант Danilka © (31.05.05 08:40) [1] наиболее приемлем. Нафига тот номер узеру до записи?
← →
Anatoly Podgoretsky © (2005-05-31 09:29) [10]Ярослав (31.05.05 09:28) [8]
Считай что они работают одновременно, поэтому могут если сделаешь неправильно.
← →
Sergey13 © (2005-05-31 09:34) [11]2 [8] Ярослав (31.05.05 09:28)
Во первых срабатывать будут не две ХП или триггера, а один тригер 2 раза. Кроме того есть еще транзакции и ограничения. Это (при правильном применении) практически непробиваемая защита.
Во вторых, я бы все таки посоветовал разнести номера документов и их ИДшники.
← →
msguns © (2005-05-31 09:34) [12]>Ярослав (31.05.05 09:28) [8]
>Но меня интересует могут ли одновременно сработать на сервере две ХП или триггера и назначить одинаковые номера?
1.Одновременно две ХП (и просто 2 запроса) на сервере не работют.
2. Для того и придуман автоинкремент, чтобы номера не повторялись.
3. Для "непрерывности" автоинкремент не походит, как и вся описанная технология. Необходимо делать самому автонумерацию (через спец. таблицу) для каждого типа документов.
4. А зачем именно непрерывность ?
← →
ANB © (2005-05-31 09:39) [13]
> Ярослав (31.05.05 09:28) [8]
- предлагаю вариант для приказов :
- В момент создания документа присваиваем ему только ИД, а номер оставляем Null.
- Когда пользователь документ полностью оформит, он отправляет его на регистрацию. Журнал регистрации можно оформить в виде отдельной таблички с автоинкрементом. Автоинкремент, если его не дергать спец.процедурами, более - менее гарантирует уникальность, а монотонность ты обеспечиваешь явной операцией регистрации и проверками до вставки.
- С момента регистрации запретить пользователю удалять документ. И вообще не разрешать менять номер ручками.
Все имхо.
← →
Ярослав (2005-05-31 09:42) [14]>> Anatoly Podgoretsky © (31.05.05 09:29) [10]
А как правильно сделать?
← →
Anatoly Podgoretsky © (2005-05-31 09:56) [15]Ну например как в 13, естественно на поле наложить ограничение уникальности. Вместо удалений документа использовать понятие аннулирование, с указанием причины. Дырок не будет, поскольку документы не удаляются, номер не изменяется. Требуемое изменение номера делается через анулирование и создание нового документа. В MSSQL есть много механизмов генерации "номеров", identity, тригера, хранимые процедуры.
Номер естественно присваивается только при регистрации.
← →
Nikolay M. © (2005-05-31 10:00) [16]Один из вариантов: придумать алгоритм, который на основе ПК-Identity-поля и, возможно, некоторых других полей таблицы (например, дата-время создания документа, его тип, юзер и тд) формирует буквенно-цифровой код. Алгоритм реализовать в функции и подставить вызов этой ф-ции в вычисляемое поле таблицы. Если номер документа нужно видеть сразу до момента физической вставки записи, такое решение будет довольно геморойным.
← →
DenK_vrtz © (2005-05-31 10:02) [17]Еще один "древний" способ.
Имеем уникальный индекс по номеру документа.
При вставке данных таблица блокируется, ищется максимальное значение номера документа, значение увеличивается на единицу. После вставки блокировка таблицы снимается.
У способа есть как свои плюсы, так и минусы.
Либо играть со спец. таблицей.
← →
ANB © (2005-05-31 10:22) [18]
> DenK_vrtz © (31.05.05 10:02) [17]
- положим, автоинкремент в мсскуле практически заменяет сиквенсы оракла. Имхо, их таки проще всего юзать. И быстрее, чем блокировка. Я блокировку только для DBF юзал, в клиппере, но там другого способа не было.
← →
Anatoly Podgoretsky © (2005-05-31 10:29) [19]DenK_vrtz © (31.05.05 10:02) [17]
И идем вешаться.
← →
Petr V. Abramov © (2005-05-31 15:10) [20]> msguns © (31.05.05 09:17) [6]
> очередной холивар ?
Да :)
> Числовой № получается автоинкрементом
Не стоит. Откатится транзакция по каким-либо причинам, и дырка готова
← →
msguns © (2005-05-31 15:27) [21]>Petr V. Abramov © (31.05.05 15:10) [20]
>> очередной холивар ?
> Да :)
Ща.. шаблю прадедову возьму.. ;)
>Не стоит. Откатится транзакция по каким-либо причинам, и дырка готова
Для ентова есть правка ручками. Если следовать основным канонам делопроизводства, то все номера документов вместо с вх/исх информацией регистрируется в отд. журналах. Куда вовсе несложно глянуть, чтобы "подсмотреть" послений номер реального док-та.
Если же таковой журнал недоступен, то нет ничего страшного в пропуске номера. Делопроизводство не допускает одинаковой нумерации, но ничего не говорит по поводу "дырок".
Строить же специально какие-то таблицы по крайней мере нерационально, т.к. придется учитывать ВСЕ ВИДЫ документов, а это не всегда удобно и даже возможно. Написать же запрос (ХП), который будет резервировать № для указанного вида документа, причем с учетом возобновления нумерации с начала года, не проблема. Конфликт же уникальности опять же легко блокируется предваряющей перед вставку проверкой.
(Шаблю зачехлил, достал щит +6 к интеллекту ;))
← →
msguns © (2005-05-31 15:29) [22]Т.е. я хочу сказать, что, конечно, не автоинкремент ;))
← →
Нулевой © (2005-05-31 15:36) [23]Я делал так:
таблица 2 поля: 1-номер док., 2-год (для того чтобы год начинать с документа № 1,... новый год опять 1)
Start транзакция
блокировка таблицы
Update записи
ОК - Commit
иначе RollBack
транзакция короткая
полученный номер присваиваю номеру док. в другой табл. имеющей свой отдельный ID записи.
работает 2-3 пользователя введено 700 записей без проблем пока,
без разрывов.
← →
Sergey13 © (2005-05-31 15:39) [24]2[23] Нулевой © (31.05.05 15:36)
>полученный номер присваиваю номеру док. в другой табл
А если это отменить?
← →
Нулевой © (2005-05-31 15:42) [25]Это уже не отменить так как все связано с кнопкой Сохранить или ОК или Добавить и т.д., отменить можно только Update в первой таблице.
← →
Нулевой © (2005-05-31 15:42) [26]Сняв естественно блокир.
← →
Sergey13 © (2005-05-31 15:48) [27]2[25] Нулевой © (31.05.05 15:42)
>Это уже не отменить так как все связано с кнопкой
Связь с кнопкой еще не гарантирует невозможность отмены (хотя бы аварийной) если внутри транзакции только апдейт первой таблицы.
← →
msguns © (2005-05-31 15:55) [28]>Нулевой © (31.05.05 15:36) [23]
>Я делал так:
таблица 2 поля: 1-номер док., 2-год (для того чтобы год начинать с документа № 1,... новый год опять 1)
Start транзакция
блокировка таблицы
Update записи
ОК - Commit
иначе RollBack
транзакция короткая
полученный номер присваиваю номеру док. в другой табл. имеющей свой отдельный ID записи.
работает 2-3 пользователя введено 700 записей без проблем пока,
без разрывов.
Круто.
Вопросы тов.лектору:
1. А если надо номер писать вот так: 2005/10 или 10/2005 или 10-05 и т.д. (что, какмправило и наблюдается в реальной жизни) ?
2. Что такое "Update записи" - это когда юзер получает формочку и срочно бежит в тулет до обеда ? Или когда он уже нажал кнопульку ? В последнем случае номера, очевидно, он не еще знает.
Если второе, то как быть с такой ситуевиной. Менагер по продажам по телефону выписывает счет (или сразу накладную), в котором надо заполнить 30 полей, а его заказчик спрашивает № чтобы бежать в банк платить. Что ему скажет менагер,- мол, обожди, паря, щас тут у меня стартанет транзакция, сработает триггерец и, ежели не будет конфликта, то я скажу тебе номер ?
3. Если есть другая таблица только для номеров, то зачем тогда в первой поле "Год" ?
4. 2-3 пользователя весьма маловероятнисто начнут ввод документов одновременно (в интервале 1-2 сек, которого вполне хватит серверу, чтобы "зарезервировать" № даже если он не autoinc
. Так что не очень убедительно.
5. Как решен вопрос о раздельной нумерации разных видов документов ?
6. Можно ли поменять № в документе ? А если нет, то как быть, если это все же необходимо ? Удалять старый и перезаводить по новому ?
7. Чем же так страшны разрывы ?
← →
Anatoly Podgoretsky © (2005-05-31 15:58) [29]Они больны головой.
← →
Нулевой © (2005-05-31 17:21) [30]
> msguns © (31.05.05 15:55) [28]
1. Без проблем
2. именно второе, ситуация со счетом не канает, у меня другая ситуация.
3. так проще.
5. раздельная нумерация не нужна.
6. можно, без проблем (во второй таблице)
7. не понял?
Все написано о лично моей задаче, так что нечего пинать.
Из всего никто автору ничего не предложил, кроме как использовать Autoinc. Но он не подходит, как и мне не подходит.
100% даст разрыв в номерах, мне это важней всего (верной для пользователя это было под №1).
> Anatoly Podgoretsky © (31.05.05 15:58) [29]
Чем хамить, что-нибудь предложите автору, причем бесплатно!
← →
Polevi © (2005-05-31 17:58) [31]для номеров документов непрерывность не нужна
для счетов фактур см [13] + возможность всеже редактировать этот номер, для того чтобы бухгалтер мог при желании сделать "дробный" номер счета-фактуры - 1234/5 - без этого иногда никак
← →
Anatoly Podgoretsky © (2005-05-31 19:15) [32]Нулевой © (31.05.05 17:21) [30]
У тебя есть проблемы, хочешь поговорить?
← →
Fay © (2005-05-31 20:22) [33]Polevi © (31.05.05 17:58) [31]
>> для номеров документов непрерывность не нужна
Но всё меняется, когда приходят ОНИ - заказчики, считающие иначе!
8)
← →
anatolyk (2005-05-31 21:46) [34]Я попытался сделать что-то вроде этого (MSSQL):
CREATE PROCEDURE [sp_GetFirstEmptyCodeByRecid]
@Recid Int
AS
select top 1 (Код+1)
from dbo.СтрокиПрайсЛистов T1
where (p_recid = @recid) and
((select top 1 Код from dbo.СтрокиПрайсЛистов T2 where (p_recid = @recid) and (код > T1.Код) order by код) - код) > 1
order by код
GO
где Код-понятно,
p_recid - id прайс-листа (с которым связаны СтрокиПрайсЛистов)
Не идеально, но работает.
← →
Johnmen © (2005-06-01 09:17) [35]Вот тут много чего наговорили, только создаётся впечатление, что многие пытаются совместить две различные сущности - суррогатный ключ, по большому счёту никакого отношения к "жизненному" номеру документа не имеющий, и собственно сам этот номер.
Не стОит этого делать.
← →
ANB © (2005-06-01 09:21) [36]
> Johnmen © (01.06.05 09:17) [35]
- смотри мой пост [13]. Я там разношу понятия ключа и номера. Имхо, никто не давал советов объединять эти понятия. Просто нужна уникальная нумерация без дырок. Проблема старая и по человечески - плохо решаемая. Например, мой способ не очень подходит для счетов (когда нужно быстро сообщить клиенту номер). На одной из работ решили проблему просто - забили на дырки.
← →
Johnmen © (2005-06-01 09:32) [37]>ANB © (01.06.05 09:21) [36]
Не стОило так однозначно относить себя ко "многим". :)
← →
ANB © (2005-06-01 09:37) [38]
> Не стОило так однозначно относить себя ко "многим". :)
- да вроде ветку посмотрел - никто и не советует номер документа за суррогат держать. Имхо. Може чего и не углядел. А вот сам я раз на грабли наступил капитально. До сих пор старый проект с такими ключами. Ух и задрался я потом перебивать ключи при изменении даты документа. Молодой был, глупый, теорию не читал, да ее тогда толком и не было, как не было автоинкрементов и сиквенсов в Clipper.
← →
Anatoly Podgoretsky © (2005-06-01 09:43) [39]Johnmen © (01.06.05 09:17) [35]
Вот тут много чего наговорили, только создаётся впечатление, что многие пытаются совместить две различные сущности - суррогатный ключ, по большому счёту никакого отношения к "жизненному" номеру документа не имеющий, и собственно сам этот номер.
Сообственно и сам номер документа - это не номер, а шифр/код документа. Номером называют по привычке и путают еще и с идентификатором записи.
← →
Тучудище (2005-06-01 10:04) [40]Давайие посмотрим в сторону 1Ц... что же мы там видим???? А видим мы там вот что....
1) Имеется табличка (1SDNLOCK.DBF для DBF) или (_1SDNLOCK для MSSQL)
2) В этой табличке имеется всего 2 поля
а) тип документа
б) номер документа
3) При создании пользователем нового документа формируется новый номер и добавляется в эту табличку
4) В случает отмены ввода документа, удалении документа номер так же изымается из вышеупомянутой таблицы
5) Большой минус всего этого в следующем:
Пусть пользователь А открыл документ и получил номер для него
Пусть пользователь Б открыл документ и получил номер для него
Пользователь Б сохранил документ
Пользователь А не сохранил документ
Номер пользователя Б стал последним
Когда номер пользователя А просто исчез
Вот пробел в нумерации готов
Это что касается присвоения номера в момент открытия нового документа.... хотя на практике 1Ц-шная система сбоя не давала(я не видел такого сопровождаю ее уже около 5 лет)
Как бы сделал я:
1) Не стал бы использовать генераторы ни в коем случае
2) Не стал бы использовать autoincrement котегорично
3) Далее идем по разветвлению,
a)если номер документа требуется в момент открытия документа(чем черт не шутит)... то ввел бы доп таблицу и последовал бы по
пути 1Ц
б)если номер присваивается после вставки документа, что менее капризно и риск пробелов в нумерации более менее ниже чем у варианта "а" то создал бы механизм который присваивает новый номер документа в момент вставки нового документа в БД
в)проводил присвоение нумерации документов в конец дня(идеально), но фиг кто даст такое сделать! :-) а жаль! :-)
Страницы: 1 2 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.57 MB
Время: 0.043 c