Is there any other better way to perform this operation?
-- USE EXAMPLE: EXEC GetFirstIdInGap @tableName ='Employees',@column='IdEmployee'
CREATE PROCEDURE GetFirstIdInGap
(@tableName sysname,
@column sysname)
AS
IF @tableName IS NOT NULL and @column IS NOT NULL
BEGIN
DECLARE @col varchar(50), @col2 varchar(50)
SET @col = 'A.' + @column;
SET @col2 = 'A2.' + @column;
EXEC ('SELECT ISNULL((MIN('+@col+') - 1),(SELECT ISNULL(MAX('+@column+')+1,1) FROM '+@tableName+'))
AS '+@column+'
FROM '+@tableName+' AS a
LEFT JOIN '+@tableName+' AS a2
ON '+@col2+' = '+@col+' - 1
WHERE '+@col2+' IS NULL AND '+@col+' > 1');
END
GO
It gets the first free ID (if there are gaps) or the last one + 1 given a @tableName and @column. If there are no rows, it returns as the first ID = 1.
UPDATE:
For those who have asked about why do I need gaps of ID’s, I am gonna explain my problem (although I didn’t want to dig into it). I work with C# Winforms applications against other firmware applications which have serious memory restrictions. One of those restrictions is that I can only use a maximum code value of 65536. Those codes are equivalent of database ID’s, and in some cases the firmware code had reached the value of 65536. That’s why gap reusing would be wonderful for me.
Here is an approach that doesn’t require a numbers table (even one with more than 1,000 rows):