SQL Server 2012 Developer SQL Server 2012 Enterprise SQL Server 2012 Standard SQL Server 2014 Developer — duplicate (do not use) SQL Server 2014 Enterprise — duplicate (do not use) SQL Server 2014 Standard — duplicate (do not use) Еще…Меньше
Проблемы
Предположим, что вы используете репликацию слиянием в Microsoft SQL Server 2012 или SQL Server 2014 и добавляете новые статьи с фильтрами соединения в существующие публикации. Когда существующие подписчики начнут синхронизироваться (сразу после добавления новых статей), а затем Синхронизация прерывается, Последующая синхронизация может завершиться с ошибкой дублирования ключа на dbo. sysmergesubsetfilters, пока не будут повторно инициализированы соответствующие абоненты. Сообщение об ошибке похоже на следующее:
Источник: репликация слиянием ProviderNumber:-2147201001Message: процессу слияния не удалось отправить моментальный снимок на подписчик. При использовании веб-синхронизации процесс слияния может быть не в процессе создания или записи в файл сообщения. При устранении неполадок запустите синхронизацию повторно, включив ведение подробного журнала и указав выходной файл для записи. Источник: Microsoft SQL Server Native Client 11.0 номер: 2601Message: не удается вставить повторяющуюся строку ключа в объект «dbo. sysmergesubsetfilters» с уникальным индексом «uc2sysmergesubsetfilters». Повторяющееся значение ключа: (<значение ключа>, <имя таблицы>).
Решение
Эта проблема впервые устранена в следующем накопительном обновлении SQL Server:
-
Накопительное обновление 2 для SQL Server 2014 с пакетом обновления 1 (SP1)
-
Накопительное обновление 9 для SQL Server 2014
-
Накопительное обновление 7 для SQL Server 2012 с пакетом обновления 2 (SP2)
Статус
Корпорация Майкрософт подтверждает наличие этой проблемы в своих продуктах, которые перечислены в разделе «Применяется к».
Нужна дополнительная помощь?
Нужны дополнительные параметры?
Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.
В сообществах можно задавать вопросы и отвечать на них, отправлять отзывы и консультироваться с экспертами разных профилей.
SQL Server Error Messages — Msg 2601 Error Message Server: Msg 2601, Level 16, State 1, Line 1 Cannot insert duplicate key row in object '<Object Name>' with unique index '<Index Name>'. Causes A unique index guarantees that the index key contains no duplicate values and therefore every row in the table in some way unique. A unique index is created by including the argument UNIQUE when creating an index using the CREATE INDEX statement. The CREATE INDEX statement creates a relational index on a specified table or view and the index can be created before there is data in the table. |
As the error message suggests, when inserting data into a table that contains a unique index and the data in the column or columns participating in the unique index already exist in the table, this error message will be raised.
To illustrate, here’s a simple table that contains a unique index on one of its columns:
CREATE TABLE [dbo].[Currency] ( [CurrencyCode] CHAR(3), [CurrencyName] VARCHAR(50) ) GO CREATE UNIQUE INDEX [IX_Currency_CurrencyCode] ON [dbo].[Currency] ( [CurrencyCode] ) GO
The following script populates the table with data of currency codes:
INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'USD', 'U.S. Dollar' ) INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'EUR', 'Euro' ) INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'GBP', 'Pound Sterling' ) INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'INR', 'Indian Rupee' )
If by accident the same script is executed, the following error message will be generated for each INSERT statement executed:
Msg 2601, Level 14, State 1, Line 2 Cannot insert duplicate key row in object 'dbo.Currency' with unique index 'IX_Currency_CurrencyCode'.
Another way of encountering this error is when inserting data to a table and the data are coming from another table. Here’s a script that illustrates this scenario.
CREATE TABLE [dbo].[Currency_New] ( [CurrencyCode] CHAR(3), [CurrencyName] VARCHAR(50) ) GO INSERT INTO [dbo].[Currency_New] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'CAD', 'Canadian Dollar' ) INSERT INTO [dbo].[Currency_New] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'SWF', 'Swiss Franc' ) INSERT INTO [dbo].[Currency_New] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'AUD', 'Australian Dollar' ) INSERT INTO [dbo].[Currency_New] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'CAD', 'Canadian Dollar' ) INSERT INTO [dbo].[Currency_New] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'JPY', 'Japanese Yen' ) INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) SELECT [CurrencyCode], [CurrencyName] FROM [dbo].[Currency_New] A WHERE NOT EXISTS (SELECT 'X' FROM [dbo].[Currency] B WHERE A.[CurrencyCode] = B.[CurrencyCode]) GO
Msg 2601, Level 14, State 1, Line 2 Cannot insert duplicate key row in object 'dbo.Currency' with unique index 'IX_Currency_CurrencyCode'.
As can be seen from the script, the source table ([dbo].[Currency_New]) contains duplicate entries for the Canadian Dollar currency (CAD).
Solution / Work Around:
When inserting literal values into a table that contains a unique index in one of its columns that serves as the table’s key, there are a couple of ways of avoiding this error message. The first method is with the use of an IF statement that checks for the existence of the new data before performing an INSERT. If the row does not yet exist in the destination table, then it can be inserted.
Here’s how the script will look like:
IF NOT EXISTS (SELECT 'X' FROM [dbo].[Currency] WHERE [CurrencyCode] = 'USD') INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) VALUES ( 'USD', 'U.S. Dollar' ) GO
The validation must be done for each set of literal values that needs to be inserted into the table.
Another way of checking for the existence of row in a table is still with the use of the NOT EXISTS statement but instead of using it in an IF statement, it can be used in the WHERE clause of a SELECT statement, as can be seen in the following script:
INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) SELECT 'USD', 'U.S. Dollar' WHERE NOT EXISTS (SELECT 'X' FROM [dbo].[Currency] WHERE [CurrencyCode] = 'USD') GO
Instead of using the VALUES clause of the INSERT statement, a SELECT statement is used to insert the data into the table. Since the data is not coming from any table, the FROM clause of the SELECT statement need not be included. Similar to the first option, this has to be done for each row of data that will be inserted into the destination table.
In the case of inserting data coming from another table and the source table contains duplicates, there are also a couple of ways of avoiding this error from being raised. The first option is simply to add the DISTINCT clause in the SELECT statement to make sure that only distinct rows will be inserted into the destination table.
Here’s an updated version of the script with the DISTINCT clause:
INSERT INTO [dbo].[Currency] ( [CurrencyCode], [CurrencyName] ) SELECT DISTINCT [CurrencyCode], [CurrencyName] FROM [dbo].[Currency_New] [New] WHERE NOT EXISTS (SELECT 'X' FROM [dbo].[Currency] [Old] WHERE [New].[CurrencyCode] = [Old].[CurrencyCode]) GO
Alternatively, the MERGE statement can be used instead of the INSERT INTO … SELECT WHERE NOT EXISTS statement. The MERGE statement performs insert, update or delete operations on a target table based on the results of a join with a source table.
Here’s how the script will look like using the MERGE statement.
MERGE [dbo].[Currency] AS [Target] USING (SELECT DISTINCT [CurrencyCode], [CurrencyName] FROM [dbo].[Currency_New]) AS [Source] ON [Target].[CurrencyCode] = [Source].[CurrencyCode] WHEN MATCHED THEN UPDATE SET [CurrencyName] = [Source].[CurrencyName] WHEN NOT MATCHED THEN INSERT ( [CurrencyCode], [CurrencyName] ) VALUES ( [Source].[CurrencyCode], [Source].[CurrencyName] ); GO
As can be seen in this MERGE statement, a DISTINCT clause is still needed in the source table. If the DISTINCT clause is not included, the following error message will be raised:
Msg 8672, Level 16, State 1, Line 2 The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
- Remove From My Forums
-
Question
-
I setup transaction replication between sql 2000 (Publisher and local distributor) and sql 2005 (Subscriber).
The db replication was running fine until I implemented a small change on Publisher server.
exec sp_changearticle ‘KM_Data’, ‘t_table1’, ‘del_cmd’, ‘NONE’
goI run the initial database snapshot and it was completed.
Then, I got an error on:
«Cannot insert duplicate key row in object’dbo.t_table2′ with unique index ‘aaa_t_table2_PK’ (Source MSSQLServer, Error number: 2601)»
Please help and advise.
Thanks,
TJ
Answers
-
In my experience, this has usually been the result of a table being altered on the publisher, with changes to an index, which have not also been implemented on the subscriber, or worse yet, for a SQL 2000 server, someone running an ALTER TABLE command instead of the appropriate sp_replcommand (e.g. sp_repladdcolumn) to make a change to a table which is replicated. Index changes are not usually replicated by the way and need to be implemented separately, unless the article subscription and the article itself is first dropped, the subscription refreshed, and then the article re-added and the subscription refreshed again, with snapshot agent run immediately after.
My suggestion would be to query the differences in data and table structure between the publisher and the subscriber versions of the table and determine what the root problem is. If it is not a simple index difference which you can then implement and try again, you may then need to drop the article, fix any existing structural differences if they exist, and then re-add the article to the publication for the issue to disappear.
Good Luck!
-
Are you doing deferred updates meaning update of primary keys. being sql 2000 you such updates will be send as a delete insert pair, if you set delete to none, the delete will not be replicated and hence can run into this scenario.
-
If you are doing deferred updates 2000 publisher will replicate that as del\ins pair. If you dont replicate deletes then you can run into this scenario. In 2005 the default in most cases is to replicated such updates as direct updates.
http://support.microsoft.com/kb/238254
- Remove From My Forums
-
Вопрос
-
I setup transaction replication between sql 2000 (Publisher and local distributor) and sql 2005 (Subscriber).
The db replication was running fine until I implemented a small change on Publisher server.
exec sp_changearticle ‘KM_Data’, ‘t_table1’, ‘del_cmd’, ‘NONE’
goI run the initial database snapshot and it was completed.
Then, I got an error on:
«Cannot insert duplicate key row in object’dbo.t_table2′ with unique index ‘aaa_t_table2_PK’ (Source MSSQLServer, Error number: 2601)»
Please help and advise.
Thanks,
TJ
Ответы
-
In my experience, this has usually been the result of a table being altered on the publisher, with changes to an index, which have not also been implemented on the subscriber, or worse yet, for a SQL 2000 server, someone running an ALTER TABLE command instead of the appropriate sp_replcommand (e.g. sp_repladdcolumn) to make a change to a table which is replicated. Index changes are not usually replicated by the way and need to be implemented separately, unless the article subscription and the article itself is first dropped, the subscription refreshed, and then the article re-added and the subscription refreshed again, with snapshot agent run immediately after.
My suggestion would be to query the differences in data and table structure between the publisher and the subscriber versions of the table and determine what the root problem is. If it is not a simple index difference which you can then implement and try again, you may then need to drop the article, fix any existing structural differences if they exist, and then re-add the article to the publication for the issue to disappear.
Good Luck!
-
Are you doing deferred updates meaning update of primary keys. being sql 2000 you such updates will be send as a delete insert pair, if you set delete to none, the delete will not be replicated and hence can run into this scenario.
-
If you are doing deferred updates 2000 publisher will replicate that as del\ins pair. If you dont replicate deletes then you can run into this scenario. In 2005 the default in most cases is to replicated such updates as direct updates.
http://support.microsoft.com/kb/238254
Search code, repositories, users, issues, pull requests…
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up