var visibilityChange = (function (window) {
var inView = false;
return function (fn) {
window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function (e) {
if ({focus:1, pageshow:1}[e.type]) {
if (inView) return;
fn("visible");
inView = true;
} else if (inView) {
fn("hidden");
inView = false;
}
};
};
}(this));
visibilityChange(function (state) {
console.log(state);
});
Найдите первую строку, где там не существует строка с идентификатором + 1
SELECT TOP 1 t1.Id+1
FROM table t1
WHERE NOT EXISTS(SELECT * FROM table t2 WHERE t2.Id = t1.Id + 1)
ORDER BY t1.Id
Править:
Для обработки особого случая, где самый низкий существующий идентификатор не 1 вот, ужасное решение:
SELECT TOP 1 * FROM (
SELECT t1.Id+1 AS Id
FROM table t1
WHERE NOT EXISTS(SELECT * FROM table t2 WHERE t2.Id = t1.Id + 1 )
UNION
SELECT 1 AS Id
WHERE NOT EXISTS (SELECT * FROM table t3 WHERE t3.Id = 1)) ot
ORDER BY 1
Действительно необходимо попытаться преобразовать столбец в ИДЕНТИФИКАЦИОННЫЕ ДАННЫЕ. СКОПИРУЙТЕ сначала затем использование ROW_NUMBER для обновления идентификатора документа, таким образом, они запускают от 1 и до количества документа. Необходимо выполнить в нем НЕКОТОРОЕ ВРЕМЯ один в то время, потому что, если столбец числа используется в качестве ссылки в других таблицах (внешние ключи), SQL Server попытается обновить внешние ключи и возможно перестать работать из-за конфликтов. В конце просто включают спецификации идентификационных данных для столбца.
:) Это - больше работы теперь, но это сохранит Вас большая проблема позже.
SELECT TOP 1 t1.id+1
FROM mytable t1
LEFT OUTER JOIN mytable t2 ON (t1.id + 1 = t2.id)
WHERE t2.id IS NULL
ORDER BY t1.id;
Это - альтернатива ответам с помощью связанных подзапросов, данных @Jeffrey Hantlin и @Darrel Miller.
Однако политика, которую Вы описываете, является действительно не хорошей идеей. Значения идентификаторов должны быть уникальными, но не должны требоваться, чтобы быть последовательными.
Что происходит, если Вы посылаете кому-то по электронной почте со ссылкой на документ № 42 и затем впоследствии удаляете документ? Позже, Вы снова используете идентификатор № 42 для нового документа. Теперь получатель электронной почты перейдет по ссылке к неправильному документу!
Если существуют разрывы в последовательности, можно найти первый разрыв с чем-то вроде этого:
select top 1 (found.id + 1) nextid from (select id from items union select 0) found
where not exists (select * from items blocking
where blocking.id = found.id + 1)
order by nextid asc
Другими словами, найдите наименьшее количество идентификатора, преемник которого не существует, и возврат тот преемник. Если нет никаких разрывов, это возвращает одно большее, чем самый большой существующий идентификатор. Идентификатор заполнителя 0 вставляется, чтобы обеспечить, чтобы идентификаторы, запускающиеся с 1, рассмотрели.
Обратите внимание, что это возьмет, по крайней мере, n, регистрируют n время.
Microsoft SQL разрешает использование a from
пункт в insert
оператор, таким образом, Вы, возможно, не должны обращаться к процессуальному кодексу.
Никакое упоминание о блокировке или параллелизме в любом из ответов до сих пор.
Рассмотрите эти двух пользователей, добавляющих документ в почти то же время:-
User 1 User 2
Find Id
Find Id
Id = 42
Id = 42
Insert (42..)
Insert (42..)
Error!
Вы любой должны: a) Обрабатывают ту ошибку и обходят цикл, снова ища следующего доступного Id, Орегон b) Берут блокировку в начале процесса, таким образом, только 1 пользователь ищет Ids в определенное время
При сортировке их по числовому идентификатору число, которое Вы ищете, будет первым, для которого ROW_NUMBER () функция не равняется идентификатору.
Существует ли причина, что это должно быть самое маленькое количество? Почему необходимо заполнить дыры?
Редактирование к рекламе ответ, так как это - бизнес-правило.
DECLARE @counter int
DECLARE @max
SET @counter = 0
SET @max = SELECT MAX(Id) FROM YourTable
WHILE @counter <= @max
BEGIN
SET @counter = @counter + 1
IF NOT EXISTS (SELECT Id FROM YourTable WHERE Id = @counter)
BREAK
END
END
(У меня нет дб удобным, таким образом, это не может быть на 100% точно, но необходимо смочь получить его оттуда),
select
MIN(NextID) NextUsableID
from (
select (case when c1 = c2 then 0
else c1 end) NextID
from ( select ROW_NUMBER() over (order by record_id) c1,
record_id c2
from myTable)
)
where NextID > 0
declare @value int
select @value = case
when @value is null or @value + 1 = idcolumn
then idcolumn
else @value end
from table
order by idcolumn
select @value + 1
Сканирует ли 1 таблица, а не 2, сканирует совпадение хэша и соединение, как верхний ответ