http://www.lplm.ru/phpBB2/viewtopic.php?t=177
http://www.lplm.ru/phpBB2/viewtopic.php?t=255
Ниже - Последний вариант. В ожидании новой версии Лоции устраивает нас на 90%
Массив(ы) = Строковый Атрибут (не привязанный к объекту)
3 функции
lsdbo.Ric_CreateTableID - Пересоздать таблицу уникальных ID (lsdbo)
lsdbo.Ric_ClearArray - Очистить массив и вернуть ID в таблицу (lsdbo)
lsdbo.Ric_RefreshArray - Заполнить массив используя ID из таблицы (lsdbo,Party)
Как работает:
- Чтобы не нарушать работу с генерацией ID самой Лоции - забираем сколько нужно ID из верхнего адресного пространства и формируем из них таблицу 'служебных' ID. (однократно)
- Выбираем из базы данные
- Через курсоры набираем наш строковый массив, при этом ID заимствуется из созданной таблицы и используется в массиве
- При очистке массива все его используемые ID возвращаются в таблицу обратно
Таким образом используется постоянный изолированный набор ID и конфликтов по уникальности ключей не возникает
Сами функции
Код: Выделить всё
/*------------------------------------------------------
* Создать таблицу уникальных ID с 'учетом' филиала
*-----------------------------------------------------*/
ALTER Procedure lsdbo.Ric_CreateTableID
(@Length int=1000, --длина таблицы
@Filial int=99999 --номер филиала (5 знаков на филиал)
)As
Begin
Declare @Row numeric(18,0) --10 знаков на ID
Set @Row =9999999999 --верхняя граница диапазона
--удалить таблицу c ID если она есть
If Exists (Select *
From dbo.sysobjects
Where dbo.sysobjects.name='RIC_Tableid')
Drop Table lsdbo.Ric_TableID
--создать новую таблицу под ID
Create Table lsdbo.Ric_TableID
(Free_id numeric(18,0),
Constraint PK_user_myid Primary key (Free_id)
)
--заполнить таблицу ID с учетом параметров
While
(Select Count(*) From lsdbo.Ric_TableID)<@Length
Begin
Insert into lsdbo.Ric_TableID(Free_id) Values(@Row*100000+@Filial)
Set @Row=(@Row-1)
End
End
Код: Выделить всё
/*------------------------------------------------------
* Если массив (атрибут id=@d_atr) не пустой:
* -очистить его (удалить все значения атрибута)
* -вернуть все используемые id массива в RIC_TableID
* Иначе
* -выйти без изменений
*-----------------------------------------------------*/
ALTER Procedure lsdbo.Ric_ClearArray
(@d_atr numeric(18,0) Output
)As
Begin
Declare @RestoreID numeric(18,0) --возвращаемый ID
--если массив(атрибут) не пустой - очистить его и вернуть все ID
If (Select count(*) From lsdbo.value_string Where attrib_id=@d_atr)<>0
Begin
Declare @CursorVarID CURSOR --настроить курсор
Set @CursorVarID=CURSOR SCROLL DYNAMIC
For
Select id --встать на массив
From lsdbo.value_string
Where attrib_id=@d_atr
For update --для обновлений
Open @CursorVarID --открыть курсор
Begin Tran --начать транзакцию
--цикл по всей таблице курсора
Fetch Next From @CursorVarID Into @RestoreID; --прочитать первое значение
While @@FETCH_STATUS = 0 --пока курсор не 'пустой'
Begin
Delete lsdbo.value_string --удалить текущую строку массива (атрибута)
Where current of @CursorVarID;
Insert into lsdbo.RIC_TableID (Free_id) --вернуть ID в таблицу
Values(@RestoreID);
Fetch Next From @CursorVarID Into @RestoreID; --прочитать следующее значение
If @@Error<>0 --если ошибка -выйти из цикла
Begin
Rollback tran --откатить транзакцию
Set @d_atr=-1 --Ret: Ошибка в время очистки
GoTo Stop;
End
End
Commit Tran --подтвердить транзакцию
Set @d_atr=1 --Ret: Массив очищен
Stop:
Close @CursorVarID; --закрыть курсор
Deallocate @CursorVarID; --и освободить ресурсы
End
Else
Set @d_atr=0 --Ret: Массив был пустой
End