Столбец идентификации не синхронизирован

У меня есть таблица со столбцом Identity в качестве первичного ключа.

Все было хорошо, пока несколько дней назад приложение, использующее эту таблицу, не начало жаловаться на нарушение PK. Сначала я думал, что это невозможно, пока не вспомнил про DBCC CHECKIDENT. . Волшебная функция сказала мне, что «текущее значение столбца» выше, чем «текущее значение идентификатора». Я RESEED до самого высокого значения, и все снова казалось хорошо.

Мой вопрос заключается в том, чтобы предотвратить повторение этого в будущем, каковы возможные причины этой проблемы с синхронизацией? И как это предотвратить?


person Adrian Godong    schedule 20.07.2009    source источник


Ответы (2)


Похоже, вам придется искать свой код, чтобы найти случаи, когда IDENTITY_INSERT включен, а затем вставляется ключ (вероятно, столбец ident с высоким номером). Вашему приложению, вероятно, повезло в прошлом, поскольку вставленное (и произвольное) значение PK находится в пределах начального значения - вероятно, из-за удалений и тому подобного.

person Josh E    schedule 20.07.2009
comment
У нас есть только одна точка вставки, через хранимую процедуру. Но да, это не мешает людям входить в систему и изменять значения через SSMS с помощью IDENTITY_INSERT. +1, спасибо! - person Adrian Godong; 21.07.2009
comment
но... но... ни один разработчик никогда не сделал бы что-то подобное, не так ли? Скажи, что это не так! :) Если у вас есть ETL-скрипты миграции, которые запускаются как часть развертывания, вы можете проверить их также, поскольку иногда требуются явные значения ident. - person Josh E; 21.07.2009
comment
Не явно. Как отключить возможность включения IDENTITY_INSERT? Есть идеи? - person Adrian Godong; 21.07.2009
comment
из eggheadcafe.com/community/aspnet/13/45107/permission.aspx Разрешения на выполнение параметра SET IDENTITY_INSERT относятся только к фиксированной серверной роли sysadmin, фиксированным ролям базы данных db_owner и db_ddladmin и владельцу объекта. Учитывая это, помимо использования пользователя sa, вы можете добавить пользователя, которому вы хотите предоставить возможность выполнять эту команду, к фиксированным ролям базы данных db_owner или db_ddladmin. - person Josh E; 21.07.2009

Вставку удостоверений не следует включать в производственной среде, если только вы не проводите плановое обслуживание и не находитесь в однопользовательском режиме в нерабочее время. Это влияет на всех, кто пытается вставить запись (ваш обычный процесс вставки приведет к ошибке, потому что он не указывает идентификатор), пока он включен, и его использование - очень плохая практика! Если у вас есть разработчики или процессы, использующие это в рабочей среде, вам необходимо немедленно переосмыслить свой процесс.

У разработчиков не должно быть прав на производство, и только этот шаг может предотвратить повторное возникновение вашей проблемы в будущем, поскольку администратор базы данных не позволит включить вставку идентификаторов, не подумав о том, на что это повлияет. Я согласен с Джошем, проверьте любой запущенный импорт ETL, в частности, найдите тот, который был запущен примерно в то время, когда возникла проблема.

Если у вас есть разработчики, изменяющие значения идентификаторов или включающие вставку идентификаторов, вам необходимо разъяснить им, почему это очень плохая практика. Значения идентификаторов не следует изменять после их вставки, так как это также влияет на все связанные таблицы.

person HLGEM    schedule 20.07.2009
comment
Я не говорил, что кто-то регулярно что-то вставлял, но это возможно. Помимо IDENTITY_INSERT, есть ли другие причины проблемы? - person Adrian Godong; 21.07.2009