Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Выправить автоинкремент  [new]
SERG1257
Member

Откуда:
Сообщений: 2695
Имеем SQL Server 2005 и таблица со структурой

create table tbl(
id int not null CONSTRAINT [DF_tbl_id]  DEFAULT ([dbo].[fn_get_max_plus_one]()),
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary (key id,ver_id)
)

Хочется избавится от функции fn_get_max_plus_one и заменить ее вызов на значение свежевставленного identity.

Вариант решения в лоб

insert into tbl (id,val) values (0,'value');
update tbl set id=scope_identity() where id=0 and ver_id=scope_identity()
не нравится двойным обновлением индекса (а если он кластерный то больше чем двойным)

Нет ли возможности избежать update.
Пока приходит в голову только
create table tbl_identity(id int not null identity primary key)
insert into tbl_identity (select 1)
declare @ident_id int
set @ident_id=scope_identity()
delete from tbl_identity where id=@ident_id
insert into tbl (id,val) values (@ident_id,'value')
Скорее всего данный вопрос уже обсасывался с достоинствами и недостатками данного подхода. Особо интересует масштабируемость (что будет если все разом кинутся вставлять записи) Буду благодарен за линк или ключевые слова для поиска
26 май 09, 01:47    [7225953]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
lepton
Member

Откуда: Протвино
Сообщений: 1261
Дело было вечером...

Вы для чего так извращаетесь? Или просто так сильно упростили задачу?

create table tbl(
id as ver_id,
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary key (id,ver_id)
)
26 май 09, 02:16    [7225969]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
SERG1257
Member

Откуда:
Сообщений: 2695
lepton
Вы для чего так извращаетесь? Или просто так сильно упростили задачу?

На данный момент в табличке возможны два типа вставок
1 новая версия известного id
2 совершенно новый id генерящийся немасштабируемым max(id)+1
Вот второй случай я и хочу выправить. Альтернатива - блокировать таблицу на момент генерации id
26 май 09, 02:31    [7225974]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
lepton
Member

Откуда: Протвино
Сообщений: 1261
create table tbl(
id int not null default scope_identity()+1,
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary key (id,ver_id)
)
26 май 09, 02:55    [7225983]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
lepton
Member

Откуда: Протвино
Сообщений: 1261
можно так попробовать, предыдущее не годится

create table tbl(
id int not null default ident_current('tbl'),
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary key (id,ver_id)
)
26 май 09, 03:02    [7225990]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
lepton
Member

Откуда: Протвино
Сообщений: 1261
lepton
можно так попробовать, предыдущее не годится

create table tbl(
id int not null default ident_current('tbl'),
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary key (id,ver_id)
)


При множественной вставке не катит
26 май 09, 03:23    [7226000]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
SERG1257
Member

Откуда:
Сообщений: 2695
Остановился на таком варианте
default null
create table tbl(
id int not null,
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary (key id,ver_id)
)

insert into tbl (id,val) values (ident_current('tbl'),'value');
Оно куда быстрее чем скан таблицы(индекса) для максимума.
Чисто интересно есть ли хотя-бы теоретическая возможность появления дубликатов.
27 май 09, 21:03    [7237013]     Ответить | Цитировать Сообщить модератору
 Re: Выправить автоинкремент  [new]
iljy
Guest
SERG1257
Остановился на таком варианте
default null
create table tbl(
id int not null,
ver_id int not null identity,
val varchar(100)
constraint tbl_pk primary (key id,ver_id)
)

insert into tbl (id,val) values (ident_current('tbl'),'value');
Оно куда быстрее чем скан таблицы(индекса) для максимума.
Чисто интересно есть ли хотя-бы теоретическая возможность появления дубликатов.


Конечно есть, но маленькая:

Транзакция_1 Транзакция_2
ident_current ident_current
insert ---
insert
Фокус в том, что ident_current ни к каким блокировкам не приводит, и соответственно в обе транзакции совершенно спокойно вернет одно значение. Насколько это вероятно - смотрите сами. 100% надежный вариант - ваш последний, с tbl_identity. Только не грузите скуль лишними размышлениями - достаточно сделать так: delete from tbl_identity
27 май 09, 21:26    [7237062]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить