2010-01-25 4 views
4

странный вопрос. я вставляю 10 000 записей или около того в таблицу, а первичный ключ не является полем «Идентификация». поэтому при вставке всех 10 000, если некоторые дубликаты, есть ли способ перейти к следующей записи в sql server insert и убедиться, что не дубликаты идут? я действительно не забочусь о том, чтобы дубликаты не вставали.первичный ключ дубликат записи обход следующей вставки

ответ

8

Используйте опцию «Игнорировать дублирующийся ключ».

Простейший способ сделать это - удалить основной ключ в SQL Server Management Studio.

Затем создайте новый указатель типа «Index», установите Is Unique на «Yes» и установите «Ignore Duplicate Keys» на «Yes». Затем вставьте свои записи. Он будет вставлять их все, кроме дубликатов. Когда вы закончите, вы можете удалить этот индекс и воссоздать свой основной ключ.

Если вы хотите метод TSQL, смотрите опцию IGNORE_DUP_KEY в вызове CREATE INDEX:

CREATE INDEX (Transact-SQL)

EDIT:

Другим способом было бы использовать LEFT JOIN между источником таблицу и записи, которые вы собираетесь вставить, и предложение GROUP BY, только вставляя записи, которые не существуют в вашем источнике. GROUP BY уничтожит ваши дубликаты в новых записях.

+0

для первичного ключа? – uirn

+1

Первичный ключ не будет нарушен, оскорбительная запись создает предупреждение, не откатывая всю объемную вставку. – JeffO

0

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

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

INSERT MyRealTable (PKField, Field1) 
SELECT x.PKField, x.Field1 
FROM MyStagingTable x 
    LEFT JOIN MyRealTable r ON x.PKField = r.PKField 
WHERE r.PKField IS NULL 

2) оберните каждую вставку в TRY...CATCH блоке проглотить ошибку PK ограничение должно произойти один (если вы используете SQL 2005 или более поздней версии).

+0

no новые записи не отмечены для дубликатов, а не только для нового существующего – uirn

+0

Используя параметр 1, вы должны просто вытащить одну запись за значение PKField из промежуточной таблицы в реальную таблицу. например вы можете иметь столбец IDENTITY в промежуточной таблице и просто получить первый экземпляр каждого значения PKField. – AdaTheDev

2

Этот пример запроса пропустить повторяющиеся строки по ПК1:

INSERT INTO Dest (PK1, Field2) 
SELECT s.PK1, s.F2 
FROM Source s 
WHERE 
(
    SELECT TOP 1 d.PK1 
    FROM Dest d 
    WHERE d.PK1 = s.PK1 
) IS NULL 
5

вам необходимо определить свой первичный ключ игнорировать дубликаты:

CREATE TABLE [dbo].[t2](
     [n] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
     [n] ASC 
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

Использование этой опции может повредить производительности:

Если ваши данные имеют небольшой процент дубликатов, тогда IGNORE_DUP_KEY может ускорить ваши вставки. Для большего количества дубликатов IGNORE_DUP_KEY может значительно замедлить их. Я создал две таблицы, раздевая вниз все ненужные детали, а именно:

CREATE TABLE t1(n INT NOT NULL PRIMARY KEY) 
GO 
CREATE TABLE [dbo].[t2](
     [n] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
     [n] ASC 
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

Если входные данные не имели никаких дубликатов, производительность обеих вставок была последовательно то же самое:

INSERT t1(n) 
SELECT n FROM dbo.Numbers 

INSERT t2(n) 
SELECT n FROM dbo.Numbers 

(Примечание что dbo. Числа имеют 1 миллион строк.) Конечно, я всегда урезал обе таблицы между моими тестами.

Если входные данные имели 1% от дубликатов, вставка с IGNORE_DUP_KEY последовательно выполняется примерно на 5% быстрее:

INSERT t1(n) 
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers 
UNION ALL 
SELECT n FROM dbo.Numbers WHERE n <10000 
) AS t 

INSERT t2(n) 
SELECT n FROM dbo.Numbers 
UNION ALL 
SELECT n FROM dbo.Numbers WHERE n <10000 

С другой стороны, если входные данные были 100% дубликаты, вставки с IGNORE_DUP_KEY последовательно выполняется по меньшей мере, 300% медленнее, как для большого набора 2 миллиона строк:

INSERT t1(n) 
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers 
UNION ALL 
SELECT n FROM dbo.Numbers 
) AS t 

INSERT t2(n) 
SELECT n FROM dbo.Numbers 
UNION ALL 
SELECT n FROM dbo.Numbers 

Как и для меньшего набора строк 200K:

INSERT t1(n) 
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers WHERE n<100000 
UNION ALL 
SELECT n FROM dbo.Numbers WHERE n<100000 
) AS t 

INSERT t2(n) 
SELECT n FROM dbo.Numbers WHERE n<100000 
UNION ALL 
SELECT n FROM dbo.Numbers WHERE n<100000 

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

Смежные вопросы