if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_GenerateIdForEntity]') and xtype = N'P')
drop procedure [dbo].[sp_GenerateIdForEntity]
GO

-- =============================================
-- Author:        Vitacore (C)
-- Create date: 2008-01-01
-- Description: Генерирует идентификатор
-- =============================================
CREATE  PROCEDURE [dbo].[sp_GenerateIdForEntity]   
@EntName varchar(256),  
@FieldName varchar(256) = 'PrimaryKey',  
@count int = 1  
as  
BEGIN 
    declare @trancount int  
    declare @rc int  
    set @rc = null  
  
    set nocount on   
    select @trancount = @@trancount  
    if @trancount = 0 begin tran  
  
    set @rc = (select id from T_ENTITY_IDS with(rowlock,xlock) where EntName = @EntName and FieldName = @FieldName)  

    /*
        Исключение для генерации ключей VCLib.ENTITIES в доступных промежутках ввиду ограничения размера холдера.
        Генерируем после взятия блокировки в целях исключения пересечений и только при запросах для одной записи.
        Если выбрали все номера до текущего счётчика, резервируем номера по старому, изменение счётчика следует фиксировать.
    */
    if (@rc is not null and @EntName = 'VCLib.ENTITIES' and @FieldName = 'PrimaryKey' and @count = 1)
    begin
        declare @eId int
        set @eId = (select ISNULL((select MIN(e.EntityID) from VCLib.T_ENTITIES e where not exists (select * from VCLib.T_ENTITIES e1 where e1.EntityID = e.EntityID + 1)), 0) + 1)
        if (@rc > @eId)
        begin
            select @eId
            return @eId
        end
    end
  
    if @rc is null  
    begin  
        insert T_ENTITY_IDS (id, EntName, FieldName) values(1+@count, @EntName, @FieldName)  
        if @@error <> 0 goto err1  
        set @rc = 1;  
    end   
    else  
    begin  
        update T_ENTITY_IDS set id = id + @count where EntName = @EntName and FieldName = @FieldName  
        if @@error <> 0 goto err1  
    end  
  
    if @trancount = 0 commit tran  

    select @rc  
    return @rc
  
    err1:  
        if @trancount = 0 rollback tran  
        declare @msg as varchar(512)  
        set @msg = 'Ошибка генерации id для '+ @EntName  
        raiserror (@msg, 18, 1)
END
GO
