2010-12-09 5 views
-2

У меня есть таблица вроде такSQL Server 2008

ID   NAME 
----------- ----------- 
1   JON 
2   JIM 
3   BOB 

(3 row(s) affected) 

Что мне нужно свой код, чтобы выбрать номер, который не выходит в колонку ID и из поместить его в файл, в данном случае это будет "4".

Что мне нужно, это начать с 1, затем проверить 2,3 и так далее, пока не найдет номер, который не существует в таблице.

Этот код должен будет находиться в SQL Server 2008

+1

Вы хотите (наивысший + 1) или первый пробел? – gbn 2010-12-09 20:28:17

+3

И вы не хотите использовать столбец Identity, потому что ... – 2010-12-09 20:28:23

ответ

5

Что вам нужно, это таблица чисел или список:

Declare @MaxValue int; 
Set @MaxValue = 100; 

With Numbers As 
    (
    Select 1 As Value 
    Union All 
    Select Value + 1 
    From Numbers 
    Where Value <= @MaxValue 
    ) 
Select Min(N.Value) 
From Numbers As N 
    Left Join MyTable As T 
     On T.Id = N.Value 
Where T.Id Is Null 
OPTION (MAXRECURSION 0) 
+1

+1, но вам может потребоваться добавить `OPTION (MAXRECURSION 0)` к этому запросу. Чтобы предотвратить бесконечный цикл CTE, вы можете ограничить количество уровней рекурсии, разрешенных для конкретного оператора, с помощью подсказки «MAXRECURSION» и значения от 0 до 32,767 в предложении OPTION операторов INSERT, UPDATE, DELETE или SELECT. Это позволяет вам управлять выполнением инструкции до тех пор, пока вы не устраните проблему с кодом, которая создает цикл. По умолчанию для сервера установлено значение 100. Когда указано 0, предел не применяется. Только одно значение MAXRECURSION может быть указано для каждого оператора. – 2010-12-09 20:35:55

1

Можете ли вы указать, почему вам это нужно? Похоже, что может быть лучший способ удовлетворить общую потребность.

Однако, если все, что вам нужно, это следующее число в последовательности, то это должно работать:

SELECT MAX(ID) + 1 FROM Table 

Edit: Я только заметил, от ответа Томаса (и снова осматривая вопрос), что похоже, что вы ищете первый пробел, который может быть или не быть следующим числом. Но я думаю, что все еще остается ... почему?

Редактировать: Я рад, что вы приняли ответ, но я все еще думаю, что к этому больше. Например, если вы просто хотите «зарезервировать» идентификатор, тогда есть несколько способов сделать это.

GUID полезны для идентификаторов, создаваемых приложением, но не должны использоваться в качестве первичных ключей по соображениям производительности. У вас может быть второй столбец как GUID и использовать его в своем приложении, позволяя простому столбцу автоинкремент быть первичным ключом. Предпринимаются дальнейшие соображения производительности, и вы должны исследовать их.

С другой стороны, есть что-то, что называется Hi/Lo Algorithm для резервирования диапазонов идентификаторов базы данных. Он использует целые числа, которые отлично подходят для индексирования и делают большие первичные ключи. Он оставляет пробелы в последовательности, но это следует ожидать в любом случае даже с регулярным автоматически созданным столбцом (например, когда запись удаляется).

Если есть требование, чтобы в идентификаторах не было пробелов, это звучит как нечетное требование к бизнесу и должно анализироваться для его истинных потребностей. Что-то вроде этого не должно перетекать в первичный ключ в сохранении данных.