Просто произвольное предположение. Попробуйте эту внутреннюю часть Ваш JSP/Servlet:
if(request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
необходимо быть уверены, что корректное кодирование передается сервлету.
В MySQL
и PostgreSQL
:
SELECT id + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
LIMIT 1
В SQL Server
:
SELECT TOP 1
id + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
В Oracle
:
SELECT *
FROM (
SELECT id + 1 AS gap
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
)
WHERE rownum = 1
ANSI
(работает везде, наименее эффективно):
SELECT MIN(id) + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
Системы, поддерживающие функции скользящего окна:
SELECT -- TOP 1
-- Uncomment above for SQL Server 2012+
previd
FROM (
SELECT id,
LAG(id) OVER (ORDER BY id) previd
FROM mytable
) q
WHERE previd <> id - 1
ORDER BY
id
-- LIMIT 1
-- Uncomment above for PostgreSQL
Мое предположение:
SELECT MIN(p1.field) + 1 as gap
FROM table1 AS p1
INNER JOIN table1 as p3 ON (p1.field = p3.field + 2)
LEFT OUTER JOIN table1 AS p2 ON (p1.field = p2.field + 1)
WHERE p2.field is null;
Внутреннее соединение с представлением или последовательностью, имеющей все возможные значения.
Нет таблицы? Сделайте стол. Я всегда держу фиктивную таблицу только для этого.
create table artificial_range(
id int not null primary key auto_increment,
name varchar( 20 ) null ) ;
-- or whatever your database requires for an auto increment column
insert into artificial_range( name ) values ( null )
-- create one row.
insert into artificial_range( name ) select name from artificial_range;
-- you now have two rows
insert into artificial_range( name ) select name from artificial_range;
-- you now have four rows
insert into artificial_range( name ) select name from artificial_range;
-- you now have eight rows
--etc.
insert into artificial_range( name ) select name from artificial_range;
-- you now have 1024 rows, with ids 1-1024
Затем,
select a.id from artificial_range a
where not exists ( select * from your_table b
where b.counter = a.id) ;
На самом деле не существует чрезвычайно стандартного способа SQL для этого, но с некоторой формой ограничивающего предложения вы можете сделать
SELECT `table`.`num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
LIMIT 1
(MySQL, PostgreSQL)
или
SELECT TOP 1 `num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
(SQL Server)
или
SELECT `num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
AND ROWNUM = 1
(Oracle)
Это работает в SQL Server - не может тестировать его в других системах, но кажется стандартным ...
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1))
Вы также можете добавить начальную точку в предложение where ...
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1)) AND ID > 2000
Итак, если у вас были 2000, 2001, 2002 и 2005 годы, а 2003 и 2004 не существовали, то вернется 2003 год.
Первое, что пришло мне в голову. Не уверен, что это вообще хорошая идея, но должно сработать. Предположим, что таблица имеет вид t
, а столбец - c
:
SELECT t1.c + 1 AS gap FROM t as t1 LEFT OUTER JOIN t as t2 ON (t1.c + 1 = t2.c) WHERE t2.c IS NULL ORD BY GAP ASC LIMIT 1
Редактировать: Это может быть на тик быстрее (и короче!):
SELECT min (t1.c) + 1 КАК промежуток ОТ t как t1 ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ t как t2 ВКЛ (t1.c + 1 = t2.c) ГДЕ t2.c ЕСТЬ NULL