Нарушение первичного ключа Sql Server 2005 в столбце идентификаторов - PullRequest
4 голосов
/ 12 июня 2009

У меня странная проблема, и мне нужна помощь, чтобы разобраться.

У меня есть база данных, в которой есть столбец идентификатора (определяемый как int, а не null, Identity, начинается с 1, увеличивается на 1) в дополнение ко всем столбцам данных приложения. Первичным ключом таблицы является столбец идентификатора, остальные компоненты отсутствуют.

Нет набора данных, который я мог бы использовать в качестве «естественного первичного ключа», поскольку приложение должно разрешать множественное представление одних и тех же данных.

У меня есть хранимая процедура, которая является единственным способом добавления новых записей в таблицу (кроме входа на сервер напрямую от имени владельца базы данных)

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

Это то же самое, что я делал первичные ключи уже около 10 лет, и никогда не сталкивался с этим.

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

Спасибо за любой совет, который вы можете дать.

Nigel

Отредактировано в 13:15 ПО ВОСТОЧНОМУ ВРЕМЕНИ 12 июня, чтобы дать больше информации

Упрощенная версия схемы ...

CREATE TABLE [dbo].[tbl_Queries](
[QueryID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[Address] [varchar](150) NOT NULL,
[Apt#] [varchar](10) NOT NULL
    ... <12 other columns deleted for brevity>
[VersionCode] [timestamp] NOT NULL,
 CONSTRAINT [PK_tbl_Queries] PRIMARY KEY CLUSTERED 
(
    [QueryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

(также удалены операторы значений по умолчанию)

Хранимая процедура выглядит следующим образом

insert into dbo.tbl_Queries
    (   FirstName,
        LastName,
        [Address],
        [Apt#]...) values
    (   @firstName,
        @lastName,
        @address,
        isnull(@apt, ''), ... )

Он даже не смотрит на столбец идентификаторов, не использует IDENTITY, @@ scope_identity или что-то подобное, это просто файл и забудьте.

Я настолько уверен, насколько могу, что значение идентификатора не было сброшено, и никто больше не использует прямой доступ к базе данных для ввода значений. Единственный раз в этом проекте, когда используется идентификационная вставка, - это первоначальное развертывание базы данных для настройки определенных значений в таблицах поиска.

Команда QA повторила попытку сразу после получения ошибки, и ей удалось успешно отправить запрос, и с тех пор они пытались воспроизвести его, но пока не удалось.

Я действительно ценю идеи людей.

Ответы [ 8 ]

6 голосов
/ 12 июня 2009

Звучит так, будто тождественное семя было повреждено или каким-то образом сброшено. Простейшим решением будет сброс начального значения до текущего максимального значения столбца идентификации:

DECLARE @nextid INT;
SET @nextid = (SELECT MAX([columnname]) FROM [tablename]);
DBCC CHECKIDENT ([tablename], RESEED, @nextid);
4 голосов
/ 12 июня 2009

Хотя у меня нет объяснения потенциальной причины, вполне возможно изменить начальное значение столбца идентификаторов. Если бы начальное число было опущено до того места, где следующее значение уже существовало бы в таблице, то это, безусловно, могло бы вызвать то, что вы видите. Попробуйте запустить DBCC CHECKIDENT (table_name) и посмотрите, что он вам даст.

Для получения дополнительной информации, проверьте эту страницу

1 голос
/ 12 июня 2009

Случайная мысль, основанная на опыте

Вы синхронизировали данные, скажем, с Red Gate Data Compare. У этого есть опция, чтобы повторно заполнить столбцы идентичности. Это вызвало проблемы для использования. И еще один проект в прошлом месяце.

У вас также могут быть явно загруженные / синхронизированные идентификаторы.

0 голосов
/ 12 июня 2009

Нарушение первичного ключа необязательно происходит из этой таблицы.

Касается ли приложение каких-либо других таблиц или вызывает какие-либо другие хранимые процедуры для этой функции? Есть ли триггеры на столе? Или сама хранимая процедура использует какие-либо другие таблицы или хранимые процедуры?

В частности, причиной может быть таблица аудита или триггер.

0 голосов
/ 12 июня 2009

Надеюсь, что это не так, но в SQL 2005 есть известная ошибка с SCOPE_IDENTITY (): http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

0 голосов
/ 12 июня 2009

Используете ли вы функции, такие как @@ identity или scope_identity (), в какой-либо из ваших процедур? если ваша таблица имеет триггеры или несколько вставок, вы можете получить неправильное значение идентификатора для таблицы, которую вы хотите

0 голосов
/ 12 июня 2009

Просто чтобы быть очень, очень уверенным ... вы не используете IDENTITY_INSERT в своей хранимой процедуре, не так ли? Некоторая логика вроде этого:

declare @id int;
Set @id=Select Max(IDColumn) From Sometable;
SET IDENTITY_INSERT dbo.SomeTable ON
Insert (IDColumn, ...others...) Values (@id+1, ...others...);
SET IDENTITY_INSERT dbo.SomeTable OFF
.
.
.

Я чувствую себя липким, просто набираю это. Но время от времени вы сталкиваетесь с людьми, которые просто никогда не понимают, что такое столбец Identity, и я хочу убедиться, что это исключено. Между прочим: если это ответ, я не буду возражать против вас, если просто удалю вопрос и никогда не признаю, что это была ваша проблема!

Можете ли вы сказать, что я нанимаю стажеров каждое лето?

0 голосов
/ 12 июня 2009

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

Но Космический Луч - хорошее объяснение;)

...