SQL Server 2008 R2-Transaktionsreplikation "Expliziter Wert für Identitätsspalte kann nicht eingefügt werden ..."

7

Im Moment habe ich eine "Identitätskrise" mit Transaktionsreplikation in SQL Server 2008 R2. Die Datenbank wird in Kompatibilität 90 ausgeführt. Es gibt eine Tabelle mit einer Identitätsspalte, die nicht repliziert werden kann. Der Fehler lautet "Es kann kein expliziter Wert für die Identitätsspalte in Tabelle '' eingefügt werden, wenn IDENTITY_INSERT auf OFF gesetzt ist (Quelle: MSSQLServer, Fehlernummer: 544)".

Das "Nicht für die Replikation" wird für diese Tabelle auf "true" gesetzt. Ich kann keine Einstellungen für die Artikel finden, um dies ebenfalls anzugeben.

Irgendwelche Ideen werden geschätzt.

user728263
quelle

Antworten:

7

Nur um hinzuzufügen, dass Sie die Replikation nicht löschen und neu erstellen müssen, nur um das Bit "Nicht für Replikation" zu ändern.

Sie können dies mit T-SQL tun, ohne einen Snapshot zu erstellen oder Ihre Replikation zu unterbrechen.

sys.sp_identitycolumnforreplication

1 = nicht zur Replikation

0 = für die Replikation und dies verursacht die Probleme mit Identitätsspalten auf der Teilnehmerseite

So ändern Sie es für alle Tabellen:

EXEC sp_msforeachtable @command1 = '
declare @int int
set @int =object_id("?")
EXEC sys.sp_identitycolumnforreplication @int, 1'

Um es für nur eine Tabelle zu ändern, ermitteln Sie zuerst die object_id der Tabelle und führen Sie sie dann unten aus

EXEC sys.sp_identitycolumnforreplication table_object_id, 1

BEARBEITEN

Unter tsql erhalten Sie eine schöne Ausgabe mit einem Befehl, der überprüft werden kann, bevor er für die gesamte Datenbank ausgeführt wird:

if exists (select 1 from sys.identity_columns where is_not_for_replication = 0)
begin
SELECT  QUOTENAME(SCHEMA_NAME(t.schema_id)) as SchemaName,  
        QUOTENAME(t.name) AS TableName, 
        c.name AS ColumnName,
        c.object_id as ObjectID,
        c.is_not_for_replication,
        'EXEC sys.sp_identitycolumnforreplication '+cast(c.object_id as varchar(20)) + ', 1 ;' as CommandTORun_SetIdendityNOTForReplication
    FROM    sys.identity_columns AS c 
        INNER JOIN  sys.tables AS t ON t.[object_id] = c.[object_id]
        WHERE   c.is_identity = 1
        and c.is_not_for_replication = 0
end
else 
print 'There are no identity columns that needs NOT FOR REPLICATION set to 1'

Für die Adventureworks-Datenbank:

Geben Sie hier die Bildbeschreibung ein

Kin Shah
quelle
1
Ich bin mir nicht sicher, ob es erwähnenswert ist, dass wir dies sowohl auf DBs als auch auf Publisher und Subscriber anwenden müssen. Vielen Dank übrigens, Ihre Antwort hat uns wertvolle Zeit gespart.
Setzamora
1
Kin wieder zur Rettung! In meinem Fall sp_msforeachtablewar ohne eine benutzerdefinierte Implementierung nicht sofort verfügbar (Azure). Also habe ich einfach alle ObjectIDvon der letzten Abfrage kopiert und einige mehrzeilige Bearbeitungen in Sublime durchgeführt.
Pimbrouwers
3

Machen Sie die Trigger auf dem Abonnenten nicht für die Replikation und stellen Sie sicher, dass die Identitätsspalte auf dem Abonnenten als nicht für die Replikation markiert ist. Dies sollte das Problem beheben.


quelle
1
Vielen Dank! Ich habe sichergestellt, dass "Nicht für die Replikation" eingestellt ist. Am Ende habe ich die Replikation gelöscht und neu erstellt. Es funktioniert jetzt. Stelle dir das vor.
user728263