[MSSQL] Дыры с таблице
От: Muxa  
Дата: 13.12.10 09:12
Оценка:
Пусть есть таблица:
CREATE TABLE TestTable(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Value] [varchar](5) NULL
)


Пытаемся вставить в нее записи:
-- OK
insert into testtable ([Value]) values ('12345')

begin tran
-- String or binary data would be truncated. The statement has been terminated.
insert into testtable ([Value]) values ('123456789')
rollback

-- OK
insert into testtable ([Value]) values ('12345')

В результате имеем дыру:
select * from testtable

ID    Value
1    12345
3    12345

При чем неважно был ли средний insert-запрос выполнен в транзакции или нет.
Кто может объяснить такое странное поведение?
Re: [MSSQL] Дыры с таблице
От: 1stein Украина  
Дата: 13.12.10 09:43
Оценка: 4 (1) +1
Здравствуйте, Muxa, Вы писали:

M>Кто может объяснить такое странное поведение?


MSDN @@IDENTITY (Transact-SQL)

Failed statements and transactions can change the current identity for a table and create gaps in the identity column values. The identity value is never rolled back even though the transaction that tried to insert the value into the table is not committed.

Will code C# for food
Re[2]: [MSSQL] Дыры с таблице
От: Muxa  
Дата: 13.12.10 09:51
Оценка:
забавно.
это считается нормальным поведением?
есть ли способ не увеличивать @@IDENTITY в случае фэйла или роллбэка?
Re[3]: [MSSQL] Дыры с таблице
От: Lloyd Россия  
Дата: 13.12.10 09:56
Оценка: +2
Здравствуйте, Muxa, Вы писали:

M>забавно.

M>это считается нормальным поведением?
M>есть ли способ не увеличивать @@IDENTITY в случае фэйла или роллбэка?

Абсолютно нормальное. Сами подумайте, как еще может работать IDENTITY при наличии нескольких паралельных вставляющих транзакций?
Re[3]: [MSSQL] Дыры с таблице
От: Sinix  
Дата: 13.12.10 09:58
Оценка: 9 (1)
Здравствуйте, Muxa, Вы писали:


M>это считается нормальным поведением?

Абсолютно.

M>есть ли способ не увеличивать @@IDENTITY в случае фэйла или роллбэка?

Использовать самописные триггеры или запрос на выборку первого отсутствующего ID. Serializable-транзакции и аццкие тормоза в подарок!

Если серьёзно — поле с Identity надо рассматривать исключительно как служебное и не пытаться организовать с его помощью последовательную нумерацию. Намекну: что вы будете делать с последовательной нумерацией после удаления записи?
Re[3]: [MSSQL] Дыры с таблице
От: Аноним  
Дата: 13.12.10 10:00
Оценка: :))
Здравствуйте, Muxa, Вы писали:

M>забавно.

M>это считается нормальным поведением?
А чем это не нормально? IDENTITY — это генерация уникального ключа, а не генерация непрерывных последовательностей.

M>есть ли способ не увеличивать @@IDENTITY в случае фэйла или роллбэка?

В принципе, возможность есть:
Убрать IDENTITY из основной таблицы, а каждый раз перед вставкой заливать данные во временную таблицу (со своим IDENTITY), а потом из неё уже — в основную, прибавляя к ключу последнее значение IDENTITY из основной таблицы.
Кроме того, что это через не то место, тут ещё можно огрести проблемы с concurrency. Но, с другой стороны, странное требование — странное решение
Re[4]: [MSSQL] Дыры с таблице
От: Muxa  
Дата: 13.12.10 10:40
Оценка:
S>Если серьёзно — поле с Identity надо рассматривать исключительно как служебное и не пытаться организовать с его помощью последовательную нумерацию.
я не пытался получить последовательную нумерацию, я думал она у меня уже есть
хотя завязки на нее не было.

S>Намекну: что вы будете делать с последовательной нумерацией после удаления записи?

ну, тут без вариантов.
хотя из этой таблицы записи не удаляются.
Re[4]: [MSSQL] Дыры с таблице
От: Muxa  
Дата: 13.12.10 10:42
Оценка:
L>Абсолютно нормальное. Сами подумайте, как еще может работать IDENTITY при наличии нескольких паралельных вставляющих транзакций?
а разве в этом случае не будет блокировки страницы или таблицы целиком?
Re[5]: [MSSQL] Дыры с таблице
От: Lloyd Россия  
Дата: 13.12.10 10:52
Оценка:
Здравствуйте, Muxa, Вы писали:

L>>Абсолютно нормальное. Сами подумайте, как еще может работать IDENTITY при наличии нескольких паралельных вставляющих транзакций?

M>а разве в этом случае не будет блокировки страницы или таблицы целиком?

Гм. Зачем?
Re[6]: [MSSQL] Дыры с таблице
От: Muxa  
Дата: 13.12.10 10:54
Оценка:
L>Гм. Зачем?
...и в правду
Re[4]: [MSSQL] Дыры с таблице
От: avpavlov  
Дата: 13.12.10 11:45
Оценка:
А>В принципе, возможность есть:
А>Убрать IDENTITY из основной таблицы, а каждый раз перед вставкой заливать данные во временную таблицу (со своим IDENTITY), а потом из неё уже — в основную, прибавляя к ключу последнее значение IDENTITY из основной таблицы.

А заодно проделать этот фокус и со всеми ссылающимися таблицами
Re[5]: [MSSQL] Дыры с таблице
От: Lloyd Россия  
Дата: 13.12.10 12:10
Оценка:
Здравствуйте, avpavlov, Вы писали:

А>>Убрать IDENTITY из основной таблицы, а каждый раз перед вставкой заливать данные во временную таблицу (со своим IDENTITY), а потом из неё уже — в основную, прибавляя к ключу последнее значение IDENTITY из основной таблицы.


A>А заодно проделать этот фокус и со всеми ссылающимися таблицами


Не совсем понятно, что имеется в виду. Причем тут ссылающиеся таблицы?
Re[6]: [MSSQL] Дыры с таблице
От: avpavlov  
Дата: 13.12.10 13:22
Оценка:
A>>А заодно проделать этот фокус и со всеми ссылающимися таблицами

L>Не совсем понятно, что имеется в виду. Причем тут ссылающиеся таблицы?


Если он будет постоянно перегенерировать ключи, то референс констрэйнты отъедут.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.