Вставка max(id)+1 для неавтоинкрементального поля

Ciget

Всем привет.Вот есть задачка: ко мне по наследству перешла БД у одной таблички которой, нету поля автоинкремента.В эту табличку мне нужно вставить данные, где новые записи должны иметь ID = isnull(max(id),0)+1Все новые записи должны содержать +1 к ИД. как сделать запросик.Структура проста:CREATE TABLE NT( [ID] [int] NULL, [KEYFIELD] [varchar](64) NULL) ON [PRIMARY]Заранее благодарен
24 ответа

Ciget

Ciget,дак а чем не устраивает тот самый isnull(max(id),0)+1 ?


Ciget

WarAnt,А ты пробывал хоть раз вставлять ? если вставлся по одной записи - все ок, ток ты вставляешь пачку ... один и тот же айдишник


Ciget

Во-первых, номер версии сервера какой?Во-вторых, задумайтесь, что будет, если двое из двух коннектоводновременно посчитают один и тот же максимум?


Ciget

WarAnt,А ты пробывал хоть раз вставлять ? если вставлся по одной записи - все ок, ток ты вставляешь пачку ... один и тот же айдишник
Ну так и вставляйте по одной записи


Ciget

Ciget,проще один раз создать новое поле с identity чем постоянно так гемороится


Ciget

iljy,2005 сервер.Ребят я все понимаю. Но бек компатибилити никто не отменял. Я прекрасно понимаю что нужно, но кастомер ни в какую не хочет трогать БД. Вы же не глупые люди, понимаете, что есть вещи которые тебе не подвластны ))Нужно вставлять все сразу!Я понимаю что будет если два юзера одновременно буду подобные вещи делать - но они этого делать не будут.Меня интересует решение. Желательно без T-SQL, обычным запросом (одним), который можно вызвать из студии (пишу на C#).


Ciget

Ciget,identity был еще с незапамятных времен и не мешает вставлять данные как по одной, так и набором записей, равно как одному, так и нескольким юзерам. Или может быть Вам просто дырок не хочется в последовательности номеров (айдишников)?


Ciget

а если без T-SQL, то на чем? стесняюсь спросить..для спящего время бодрствования равносильно сну


Ciget

iljy,2005 сервер.Ребят я все понимаю. Но бек компатибилити никто не отменял. Я прекрасно понимаю что нужно, но кастомер ни в какую не хочет трогать БД. Вы же не глупые люди, понимаете, что есть вещи которые тебе не подвластны ))Нужно вставлять все сразу!Я понимаю что будет если два юзера одновременно буду подобные вещи делать - но они этого делать не будут.Меня интересует решение. Желательно без T-SQL, обычным запросом (одним), который можно вызвать из студии (пишу на C#).
isnull(max(id),<b>0</b>)+row_number()over(order by (select <b>0</b>))
?


Ciget

Ciget,
declare @t table( id int, val int)

insert @t
select <b>1</b>,<b>1</b> union all
select <b>3</b>,<b>2</b> union all
select <b>8</b>,<b>3</b> union all
select <b>9</b>,<b>4</b>


insert @t
select ROW_NUMBER() over(order by (select <b>1</b>)) + maxid, x from
(select isnull(MAX(id),<b>0</b>) maxid from @t) t1,
(select <b>5</b> x union all select <b>6</b> union all select <b>7</b>) t2

select * from @t


Ciget

iap, iljyавтору "бек компатибилити" нада...


Ciget

WarAnt,А ты пробывал хоть раз вставлять ? если вставлся по одной записи - все ок, ток ты вставляешь пачку ... один и тот же айдишник
Тыкать конечно было не обязательно, да я пробовал и по одной и пачками:)для пачек лучше всего сделать времянку с идентити, а уж оттуда переносить все тем же isnull(max(id),0)+1 только вместо 1 подставить поле идентити из времянки, усе:)и не надо так волноваться, нервные клетки они знаете не восстанавливаются. удачи.


Ciget

Ciget,
declare @t table( id int, val int)

insert @t
select <b>1</b>,<b>1</b> union all
select <b>3</b>,<b>2</b> union all
select <b>8</b>,<b>3</b> union all
select <b>9</b>,<b>4</b>


insert @t
select ROW_NUMBER() over(order by (select <b>1</b>)) + maxid, x from
(select isnull(MAX(id),<b>0</b>) maxid from @t) t1,
(select <b>5</b> x union all select <b>6</b> union all select <b>7</b>) t2

select * from @t
А я-то, просто max написал, как школьник! Конечно же, MAX надо вычислить коррелированным подзапросом.


Ciget

iap, iljyавтору "бек компатибилити" нада...
2005 сервер.
Что не так?


Ciget

Что не так?
Подумалось, что он хочет, чтобы и 2000-го работало... А остальное понравилось


Ciget

Подумалось, что он хочет, чтобы и для 2000-го работало... А остальное понравилось


Ciget

iap, iljyавтору "бек компатибилити" нада...
Без представления источника данных так ответить трудно.Потому что нумеровать источник придётся, подсчитывая COUNT(*) предыдущих записей,а это зависит от наличия полей с определёнными свойствами (уникальность, например)...


Ciget

isnull(max(id),<b>0</b>)+row_number()over(order by (select <b>0</b>))
?
Не работает(


Ciget

iap,ок щас постараюсь набросать.Они не уникальны.


Ciget

Не работает(
"из студии (пишу на C#)" не работает ?


Ciget

Glory,Из SQL Server management Studio пробую - не пашет, вычисляет уникальное значение - для первой записи, все остальные - дубляж


Ciget

Ciget,что не пашет-то? днс не днсит?


Ciget

Glory,Из SQL Server management Studio пробую - не пашет, вычисляет уникальное значение - для первой записи, все остальные - дубляж
Коснтрукция isnull(max(id),0)+row_number()over(order by (select 0)) вообще ничего вычислять не можетПотому что не является законченным запросом


Ciget

Коснтрукция isnull(max(id),0)+row_number()over(order by (select 0)) вообще ничего вычислять не можетПотому что не является законченным запросом
INSERT INTO [NT] ([KEYFIELD], ID) 
select distinct KEYFIELD, (select isnull(max(ID),<b>1</b>)+row_number()over(order by (select <b>0</b>)) as rt from NT)) from [NT]