A disztributor halála :-) (hu)

Ma is kijutott a jóból, de hogy teljes egyen a nap egy finom kis replikációs hibába is belefutottam:

Replication-Replication Distribution Subsystem: agent %s failed. Procedure or function sp_MSupd_dboYourObjectNameComesHere has too many arguments specified.

Jujj de jó :-) a replikáció beépített update kódja megadta magát. Sem a publikáción sem a táblán nem történt változás, egyszer csak megadta magát. Időm nem volt sok keresgélni az okokat, így inkább újrageneráltam a replikációs eljárásokat az alábbiak szerint:

  • sp_scriptpublicationcustomprocs eljárással kigenerálam az összes kódot
  • kivettem a hibás kódhoz tartozó részt és lefutattam a subscriber-en. Íme egy példa: futtassuk le az alábbi kódot azon az adatbázison, ami ki van publikálva.
1EXEC sp_scriptpublicationcustomprocs 'publication_name'

Értelemszerűen a publication_name helyére a publikációnk nevét kell írni. A kigenerált kódból keressük ki az alábbi részeket:

  • a DROP PROCEDURE részt, ami az sp_MSupd_XXX eljárásra vonatkozik,
  • ahol a dbo.MSreplication_objects táblából kitörli a replikációs eljárást,
  • a CREATE PROCEDURE részt,
  • végül, ahol újra berakja a dbo.MSreplication_objects táblába az eljárást. Az alábbi példa szerinti kódnak kellene meglenni:
 1if object_id(N'[sp_MSupd_dboMyTableObject]', 'P') > 0      
 2drop proc [sp_MSupd_dboMyTableObject]
 3go
 4if object_id(N'dbo.MSreplication_objects') is not null
 5delete from dbo.MSreplication_objects
 6where object_name = N'sp_MSupd_dboMyTableObject'
 7go
 8create procedure [sp_MSupd_dboMyTableObject]
 9 @c1 uniqueidentifier = null,@c2 uniqueidentifier = null,@c3 uniqueidentifier = null,
10 @pkc1 uniqueidentifier
11,@bitmap binary(2)
12as
13begin
14if ( substring(@bitmap,1,1) & 1 = 1 )
15begin
16update [dbo].[MyTableObject] set
17 [col1] = case substring(@bitmap,1,1) & 1 when 1 then @c1 else [col1] end
18,[col2] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [col2] end
19,[colN] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [colN] end
20where [col1] = @pkc1
21if @@rowcount = 0
22    if @@microsoftversion>0x07320000
23        exec sp_MSreplraiserror 20598
24end
25else
26begin
27update [dbo].[MyTableObject] set
28 [col2] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [col2] end
29,[colN] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [colN] end
30where [col1] = @pkc1
31if @@rowcount = 0
32    if @@microsoftversion>0x07320000
33        exec sp_MSreplraiserror 20598
34end
35end
36go
37if columnproperty
38(object_id(N'dbo.MSreplication_objects'), N'article', 'AllowsNull') is not null
39exec ('insert dbo.MSreplication_objects
40(object_name, publisher, publisher_db, publication, article, object_type) values
41( + N''sp_MSupd_dboMyTableObject'' ,
42    N''publisherservername'' ,
43    N''published_databasename'' ,
44    N''publication_name'' ,
45    N''MyTableObject'' ,''P'')')
46go

Ha jól csináltunk mindent, a replikáció helyreáll, anélkül, hogy újra kellene inicializálni vagy publikálni. Fontos megjegyezni, hogy ez csak az update eljárást fogja frissíteni, illetve csak akkor megoldás ez, ha Error: 14151, Severity: 18, State: 1. hibaüzenettel együtt jár és az SQL Server által generált Statement Delivery kóddal dolgozunk. Ha saját kódot használunk, érdemes megnézni, hogy változott e a publikált tábla definiciója és/vagy az általunk írt kód minden oszlopra rendesen meg van írva.