Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как имитировать автоинкремент? / 10 сообщений из 10, страница 1 из 1
14.10.2002, 15:16:59
    #32058023
Как имитировать автоинкремент?
Здравствуйте.
Для получения номера договора нужно организовать нечто вроде автоинкремента. Пытаюсь сделать так: в базе храню номер следующего договора. При помощи хранимой процедуры получаю этот номер и сразу его увеличиваю на единицу.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create procedure GET_NEXT_CONTRACT_NUMBER (@number int output)
As
begin
  select @number = - 1 ;
  set transaction isolation level serializable
  begin tran;
  select @number = cast(value as int) from el_mkb_value_list 
    where val_group = 'NEXT_CONTRACT_NUMBER';
  update el_mkb_value_list set value = cast(@number +  1  as varchar)
    where val_group = 'NEXT_CONTRACT_NUMBER';
  commit;
  set transaction isolation level read committed
  return ( 0 )
end


Проблема вот в чем: запускаю отладчик, дохожу до строки обновления номера. В QA еще раз запускаю на выполнение эту хранимую процедуру (имитация одновременного запроса от нескольких пользователей). Надеюсь, что второй запуск ХР дождеться пока отработает первый. Но получаю в ответ:

Your transaction (process ID #9) was deadlocked with another process and has been chosen as the deadlock victim. Rerun your transaction.

Почему второе обращени обрываеться? Может можно как-то проще реализовать инкремент?

Овчинников Денис
...
Рейтинг: 0 / 0
14.10.2002, 15:25:35
    #32058027
Trong
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create table tst (
id int identity ( 1 ,  1 ) primary key,
name varchar( 20 )
)

insert into tst values('name')
select scope_identity()
...
Рейтинг: 0 / 0
14.10.2002, 15:32:42
    #32058032
JAN
JAN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
Следующую конструкцию активно использую (очень активно) уже более года:

CREATE TABLE [NewID] (
[id] [int] NOT NULL
)GO

CREATE PROCEDURE GetNewID
AS
DECLARE @next_id int
BEGIN TRANSACTION
UPDATE NewID SET ID = ID + 1
SELECT @next_id = ID FROM NewID
COMMIT TRANSACTION
RETURN @next_id
GO


Чего и Вам желаю.
...
Рейтинг: 0 / 0
14.10.2002, 15:36:03
    #32058033
Как имитировать автоинкремент?
Trong'у

Нет у меня в хелпе функции scope_identity(). У меня MS SQL 7. Так что я Вашу идею не понял. Можете обьяснить на пальцах?

Овчинников Денис
...
Рейтинг: 0 / 0
14.10.2002, 15:41:22
    #32058035
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
Поменяйте порядок, в начале update а потом select и уровень изоляции менять не надо будет.
Разумеется и update и select внутри одной транзакции.
...
Рейтинг: 0 / 0
14.10.2002, 15:43:53
    #32058037
Trong
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
2 Денис:
а @@identity есть? это аналог.
...
Рейтинг: 0 / 0
14.10.2002, 16:03:36
    #32058046
Как имитировать автоинкремент?
2 Trong

Понял, но это не совсем то, что мне нужно.

2 Genady

Хороший совет. Пожалуй так и поступю.

Овчинников Денис
...
Рейтинг: 0 / 0
14.10.2002, 16:30:42
    #32058052
ziktuw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
можно и не мянять местами update c select'ом. Достаточно у селекта выставить хинт UPDLOCK и дидлок перестанет появляться.
...
Рейтинг: 0 / 0
14.10.2002, 19:06:46
    #32058156
Maxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
Може так поможет?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
declare @index int
set @index = (select max(id) from Table)
if @index= 0 
 begin
  set @index= 1 
 end
else
 begin
  set @index = @index+ 1 
 end
...
Рейтинг: 0 / 0
14.10.2002, 19:21:33
    #32058164
VVG_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как имитировать автоинкремент?
MSSQL позволяет делать и так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE [NewID] ( 
[id] [int] NOT NULL 
)
GO 
insert into NewID select  0 
GO
CREATE PROCEDURE GetNewID 
@NewID int output
AS 
UPDATE NewID SET @NewID = ID = ID +  1  
SELECT @NewID 
GO 

Транзакции отдыхают. :)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как имитировать автоинкремент? / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]