SQL Server находит первый пробел между полями идентификатора ключа - PullRequest
1 голос
/ 15 сентября 2011

Есть ли другой лучший способ выполнить эту операцию?

-- 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

Он получает первый свободный идентификатор (если есть пробелы) или последний +1 с данными @tableName и @column. Если строк нет, возвращается первый идентификатор = 1.

UPDATE:

Для тех, кто спросил о том, зачем мне нужны пробелы в удостоверениях личности, я объясню свою проблему (хотя я не хотел в нее вникать). Я работаю с приложениями C # Winforms против других приложений прошивки, которые имеют серьезные ограничения памяти . Одним из таких ограничений является то, что я могу использовать только максимальное значение кода 65536. Эти коды эквивалентны идентификаторам базы данных, а в некоторых случаях код встроенного программного обеспечения достиг значения 65536. Вот почему повторное использование пробелов было бы замечательно для меня. 1012 *

Ответы [ 3 ]

3 голосов
/ 15 сентября 2011

т твой стол

select 
coalesce((select min(id)+1 from t mt where not exists(select 1 from t where id+1 = mt.id )), 1) firstgap
1 голос
/ 15 сентября 2011

Вот подход, который не требует таблицы чисел (даже с более чем 1000 строк):

CREATE PROCEDURE dbo.GetFirstIdInGap_2
    @table  SYSNAME,
    @column SYSNAME
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sql NVARCHAR(MAX) = N';WITH c AS
        (
            SELECT n = ' + @column + ', 
              rn = ROW_NUMBER() OVER (ORDER BY ' + @column + ')
            FROM ' + @table + '
        )
        SELECT ' + @column + ' = 1 + COALESCE(
            (SELECT MIN(c.n) FROM c INNER JOIN c AS n
            ON n.rn = c.rn + 1 WHERE n.n - c.n > 1),
            (SELECT MAX(c.n) FROM c),
            0);';

    EXEC sp_executesql @sql;
END
GO
0 голосов
/ 12 февраля 2013

t ваш стол

select  min(isnull(id,0)+1) from t where  isnull(id,0) + 1 not in (select isnull(id,0) from t)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...