Hi, многоуважаемый All!

Есть табличка шапок документов скажем

CREATE TABLE DOC (
    ID        BIGINT,
    TYPE_ID   BIGINT,
    DATE_DOC  TIMESTAMP,
    NUM       BIGINT,
    UserNUM   BIGINT,
    From_ID   BIGINT,
    TO_ID     BIGINT,
    ...........
);

1) Есть условие что нумерация (NUM) для каждого типа документов (type_id)
   должна быть уникальной

2) Есть условие что для каждого контрагента получателя (To_ID), в зависимости
   от типа документа (Type_id) идёт своя нумерация

Нужно обеспечить уникальность нумерации документов по вышеизложенным критериям
и желательно с минимальными "дырками" в нумерации ...
Например:

ID         Type_id            Num       ToID      UserNum
 1             1               1          1          1
 2             1               2          2          1
 3             1               3          1          2
 4             2               1          1          1

и т.д.

  Естественно типов документов много, а контрагентов и того больше
  на каждый случай генератора не заведёшь ...

  Сейчас нумерация производиться через SP с использованием семафора
  в виде генератора ... Что-то типа (упрощая):

CREATE PROCEDURE DOC_PROVODKA (
    doc_id bigint)
as
declare variable i bigint;
declare variable tid bigint;
declare variable ftid bigint;
begin
// Stop - семафор,
// sleep - UDF наподобие Application.ProcessMessages в Delphi
  while (gen_id(stop, 0) <> 0)) do sleep(100);
  i = gen_id(stop, 1);

  select TYPE_ID, to_id from vw_doc where id = :doc_id into :tid, :ftid;

  select max(num) from doc where TYPE_ID = :tid into :i;
  update doc set num = z(:i) + 1 where id = :doc_id;

  select max(UserNUM) from doc where TYPE_ID = :tid and to_id = :ftid into :i;
  update vw_doc set UserNUM = z(:i) + 1 where id = :doc_id;

  i = gen_id(stop, -1);
end

Естественно всё это запускается в ReadCommitted транзакции с AutoCommit.

Вопрос: когда я, с таким подходом, напорюсь на грабли ? И на какие ?
А если серьёзно, кто что думает по этому поводу ?
Если можно, подскажите варианты решения ... желательно опробованные на
практике ...

PS: Знаю что так делать нельзя - пришлось ...
    Но текущая ситуация выводит меня из равновесия ...
    Вот и решил спросить мож кто что-то дельное подскажет ?

С уважением,
Константин Григорьевич.
===============
Двоечник на любое - Надо! отвечает - Зачем?


Ответить