2009-06-12 6 views
4

У меня запуталась странная проблема, и мне нужна помощь, чтобы понять это.Нарушение основного ключа Sql Server 2005 в столбце Identity

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

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

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

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

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

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

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

Найджел

Отредактировано на 1:15 PM EDT июня 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 снова попыталась сразу же после получения ошибки и смогла отправить запрос успешно, и с тех пор они пытались воспроизвести его и до сих пор не преуспели.

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

+0

Хммм ... есть ли шанс, что вы можете вставить схему очищенной таблицы и/или заявление о нарушении правил? – ristonj

+0

Вы все еще не можете добавить новые записи, или это произошло только один раз? –

+0

проверить мой ответ ниже Найджела ... – Eric

ответ

1

Случайные мысли основаны на опыте

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

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

+0

Нет, это произошло в настройке базы данных специально для QA около двух недель назад. База данных была развернута из VSTS Team Suite версии 2008 года и заполнена 500 сгенерированными записями. С тех пор они добавили около 50 записей как до, так и после отчета о проблеме. – Nigel

+0

Кто-то либо запустил DBCC CHECKIDENT, либо SET IDENTITY_INSERT ON, а затем – gbn

4

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

Для получения дополнительной информации, ознакомьтесь с this page

+0

Да, это была моя первая реакция на кишок: стол, возможно, был разыгран, и значение IDENTITY было сброшено или что-то в этом роде. –

+1

Или кто-то вставил значения в таблицу с включением SET IDENTITY_INSERT ON. –

+0

Спасибо Адаму, я не знал об этой команде, однако это не помогло. Сообщалось о текущем значении как 550, а максимальное значение столбца - 550 и соответствует тому, что я вижу. – Nigel

6

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

DECLARE @nextid INT; 
SET @nextid = (SELECT MAX([columnname]) FROM [tablename]); 
DBCC CHECKIDENT ([tablename], RESEED, @nextid); 
+1

Вы пытались запустить это самостоятельно? Когда-либо? – gbn

+1

Я не тестировал свое утверждение, поэтому я переписал его –

+0

Я бы второй этот. Я не вижу никакого способа дублировать значения, если семя не было отброшено. Я предполагаю, что коррупция могла произойти, но я использую SQL в течение 10 лет и видел только коррупцию один раз в сценарии с низким дисковым пространством. –

0

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

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

0

Просто сделать очень, очень уверен ... вы не используете 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

Да, я проверил, и нет IDENTITY_INSERT в хранимых процедурах. Единственное место, где я нашел, было в первых запросах, которые запускаются для заполнения данных поиска (разные таблицы, чем те, у кого проблема). – Nigel

0

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

+0

Это приведет к повреждению данных, но не к нарушению первичного ключа в таблице с столбцом идентификации, если только он не вставляет явные значения идентичности. –

0

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

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

В частности, это может вызвать стол или триггер аудита.

+0

Сообщение об ошибке, которое мы получили с сервера, указало, что именно эта таблица выдавала ошибку. Хранимая процедура не касается других таблиц или вызова другой хранимой процедуры. Существует триггер обновления, но первое, что он делает, это проверить, действительно ли это обновление (т. Е. Удаленная псевдо-таблица не пуста). Я думаю, что я собираюсь записать это до космических лучей (мой менеджер соглашается с тем, что, поскольку он не воспроизводится, мы можем игнорировать его, если он не возвращается). – Nigel