Дублирующиеся значения в столбце идентификаторов - PullRequest
2 голосов
/ 02 июля 2010

У меня есть таблица, в которой есть столбец с именем id, который имеет тип Identity. Но этот столбец содержит повторяющиеся значения 1..8, а затем снова 1..10

Как в мире это возможно?

Ответы [ 5 ]

3 голосов
/ 02 июля 2010

Я проверил, что говорит Джогри, и если вы включите Спецификацию идентичности (по крайней мере в 2008 году, возможно, и в других версиях) после того, как в таблице появятся строки, БД начнет нумерацию с наибольшего целочисленного значения. Если у вас есть одна строка со 100 в качестве значения столбца, а затем включите Identity, следующая вставка будет 101. Даже если для Identity Seed указано значение 1. Это было не то, что я ожидал, а то, что произошло.

В дополнение к SET IDENTITY INSERT есть также команда повторного заполнения. DBCC CHECKIDENT команда, которая вернет ваши значения идентичности обратно к тому, что вы указали.

Учитывая, что включение спецификации идентификатора фактически начинается с самого высокого целого числа в столбце, кто-то, вероятно, либо использовал SET IDENTITY_INSERT, либо сделал DBCC CHECKIDENT.

Самый быстрый способ повторного упорядочения, как говорит Андомар, - это удалить / воссоздать столбец, подобный этому

ALTER TABLE tbl
DROP COLUMN ident_column
GO
alter TABLE tbl
ADD ident_column int IDENTITY

SET IDENTITY_INSERT документы: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx
DBCC CHECKIDENT документы: http://msdn.microsoft.com/en-us/library/aa258817(SQL.80).aspx

2 голосов
/ 02 июля 2010

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

1 голос
/ 02 января 2014

Пример дублирующегося значения в столбце идентификаторов 'RecNo' с использованием IDENTITY_INSERT:

create table names(RecNo INT IDENTITY (1,1), name VARCHAR(50))
insert into names(name) VALUES ('maria')
insert into names(name) VALUES ('maria2')

set IDENTITY_INSERT names ON
insert into names(RecNo, name) VALUES (1, 'maria3')
set IDENTITY_INSERT names OFF

select * from names

RecNo   name
1           maria
2           maria2
1           maria3

Когда установлен параметр identity_insert, желательно не изменять его (чтобы разрешить явные значения).Пример повторяющегося значения в столбце идентификатора 'RecNo' путем повторной установки seed:

create table names(RecNo INT IDENTITY (1,1), name VARCHAR(50))
insert into names(name) VALUES ('maria')
insert into names(name) VALUES ('maria2')

DBCC CHECKIDENT(names, RESEED, 1)
insert into names(name) VALUES ('maria3')
set IDENTITY_INSERT names OFF

select * from names;

RecNo   name
1          maria
2          maria2
2          maria3
1 голос
/ 02 июля 2010

Идентичность - это просто новое значение по умолчанию.Уникальность обеспечивается ограничениями primary key и unique.

Дубликаты в столбце идентификаторов можно объяснить следующим образом:

  • В определении столбца в какой-то момент не было идентификатора по умолчанию.вовремя (как говорит Георгий)
  • Опция SET IDENTITY INSERT TableName ON была включена в определенный момент времени

Чтобы исправить эту ситуацию, отбросьте и заново создайте столбец идентификации.

0 голосов
/ 02 июля 2010

Если личность не участвует в отношениях, да, вы можете удалить ее и создать заново. Если есть отношения, ситуация более сложная.

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

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

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

...