Показать сообщение отдельно
Старый 07.05.2009, 16:49   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Предложу свой вариант пакета на PL\SQL реализующий подобные задачи при работе с данными Аксапты извне для Oracle. Написан давно, лет 5 назад, багов вроде не отмечено... Коментариями не "злоупотреблял", вроде в целом всё и так ясно, код несложный. Есть определённые допущения, например хранится только один кэш номеров, для последней компании . Писано для 3.0. Будут вопросы - с удовольствием отвечу.

X++:
CREATE OR REPLACE 
PACKAGE pck_ax_sequence Authid Current_user
Is
   --    RecId
   Procedure P_set_cache_size ( Parm_cache_size In Pls_integer );

   --   Recid
   Function F_nextval ( Parm_dataareaid In Varchar2 )
      Return Number;
End;
/

CREATE OR REPLACE 
Package Body pck_ax_sequence
Is
   L_cache_next_size             Pls_integer := 10;
   L_cache_curr_size             Pls_integer;

   Type T_cache_table Is Table Of Number
      Index By Pls_integer;

   Lt_cache_table                T_cache_table;
   L_index                       Pls_integer;   -- 1 .. L_cache_curr_size
   L_last_dataareaid             Varchar2(5);

   Procedure P_set_cache_size(
      Parm_cache_size            In       Pls_integer)
   As
   Begin
      L_cache_next_size := Parm_cache_size;
   End;

   Procedure P_init(
      Parm_dataareaid            In       Varchar2)
   As
      Pragma Autonomous_transaction;
      L_new_nextval                 Number;
   Begin
      L_cache_curr_size := L_cache_next_size;

      Update    Systemsequences
            Set Nextval = Nextval + L_cache_curr_size
          Where Dataareaid = Parm_dataareaid
            And Recid = -1
            And Name = 'SEQNO'
      Returning Nextval
           Into L_new_nextval;

      L_last_dataareaid := Parm_dataareaid;
      L_index := 1;

      For I In 1 .. L_cache_curr_size Loop
         Lt_cache_table(I) := L_new_nextval - L_cache_curr_size - 1 + I;
      End Loop;

      Commit;
   End;

   Procedure P_check_nextval(
      Parm_dataareaid            In       Varchar2)
   As
   Begin
      If    L_last_dataareaid <> Parm_dataareaid
         Or L_index > L_cache_curr_size
         Or L_index Is Null Then
         P_init(Parm_dataareaid);
      End If;
   End;

   Function F_nextval(
      Parm_dataareaid            In       Varchar2)
      Return Number
   As
   Begin
      P_check_nextval(Parm_dataareaid);
      L_index := L_index + 1;
      Return Lt_cache_table(L_index - 1);
   End;
End;
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: mazzy (2), aidsua (1), Crusader3000 (1).