Angeben der Weitergabemethode für Änderungen bei Transaktionsartikeln

Bei der Transaktionsreplikation können Sie angeben, wie Datenänderungen vom Verleger an den Abonnenten weitergegeben werden. Für jede veröffentlichte Tabelle können Sie eine von vier Methoden angeben, mit der jeder Vorgang (INSERT, UPDATE oder DELETE) an den Abonnenten weitergegeben werden soll:

  • Angeben, dass die Transaktionsreplikation eine gespeicherte Prozedur zur Weitergabe von Änderungen an die Abonnenten ausgibt und anschließend aufruft (Standardeinstellung).

  • Angeben, dass die Änderungen mithilfe einer INSERT-, UPDATE- oder DELETE-Anweisung weitergegeben werden sollen (Standardeinstellung bei Nicht-SQL Server-Abonnenten).

  • Angeben, dass eine benutzerdefinierte gespeicherte Prozedur verwendet wird.

  • Angeben, dass diese Aktion auf keinem Abonnenten ausgeführt wird. Transaktionen dieses Typs werden nicht repliziert.

Bei der Transaktionsreplikation erfolgt die Weitergabe von Änderungen an die Abonnenten standardmäßig mithilfe einer Gruppe von gespeicherten Prozeduren, die auf den einzelnen Abonnenten installiert werden. Wenn eine Einfügung, Aktualisierung oder Löschung an einer Tabelle auf dem Verleger vorgenommen wird, wird der Vorgang in einen Aufruf an eine gespeicherte Prozedur auf dem Abonnenten übersetzt. Die gespeicherte Prozedur akzeptiert Parameter, die den Spalten in der Tabelle zugeordnet sind, und lässt das Ändern dieser Spalten auf dem Abonnenten zu.

So legen Sie die Propagierungsmethode für Datenänderungen an Transaktionsartikeln fest

Standardmäßige und benutzerdefinierte gespeicherte Prozeduren

Die folgenden drei Prozeduren werden von der Replikation standardmäßig für jeden Tabellenartikel erstellt:

  • sp_MSins_<tablename> behandelt Einfügungen.

  • sp_MSupd_<tablename> behandelt Aktualisierungen.

  • sp_MSdel_<tablename> behandelt Löschungen.

Der in der Prozedur verwendete <tablename> hängt davon ab, wie der Artikel der Veröffentlichung hinzugefügt wurde und ob die Abonnementdatenbank eine Tabelle mit demselben Namen und einem anderen Besitzer enthält.

Jede dieser Prozeduren kann durch eine benutzerdefinierte Prozedur ersetzt werden, die Sie beim Hinzufügen eines Artikels zur Veröffentlichung angeben. In einer Anwendung verwendete benutzerdefinierte Prozeduren erfordern eine benutzerdefinierte Logik: z. B. das Einfügen von Daten in eine Überwachungstabelle, wenn eine Zeile auf einem Abonnenten aktualisiert wird. Weitere Informationen zum Angeben von benutzerdefinierten gespeicherten Prozeduren finden Sie in den oben aufgeführten Themen.

Wenn Sie die Standardreplikationsprozeduren oder benutzerdefinierten Prozeduren angeben, geben Sie auch eine Aufrufsyntax für jede Prozedur an (bei Verwendung von Standardprozeduren werden diese Prozeduren von der Replikation ausgewählt). Die Aufrufsyntax legt die Struktur der für die Prozedur bereitgestellten Parameter fest und welche Informationen bei jeder Datenänderung an den Abonnenten gesendet werden. Weitere Informationen finden Sie im Abschnitt zur Aufrufsyntax für gespeicherte Prozeduren in diesem Thema.

Überlegungen zum Verwenden benutzerdefinierter gespeicherter Prozeduren

Berücksichtigen Sie bei der Verwendung benutzerdefinierter gespeicherter Prozeduren die folgenden Überlegungen:

  • Sie müssen den Support für die Logik der gespeicherten Prozedur selbst übernehmen. Microsoft stellt für benutzerdefinierte Logik keinen Support bereit.

  • Verwenden Sie keine expliziten Transaktionen in benutzerdefinierten Prozeduren, um Konflikte mit Transaktionen zu vermeiden, die von der Replikation verwendet werden.

  • Das Schema auf dem Abonnenten ist in der Regel mit dem Schema auf dem Verleger identisch, kann bei Verwendung der Spaltenfilterung jedoch eine Teilmenge des Verlegerschemas sein. Wenn Sie jedoch beim Verschieben der Daten das Schema so transformieren, dass das Schema auf dem Abonnenten keine Teilmenge des Schemas auf dem Verleger darstellt, ist SQL Server 2008 Integration Services (SSIS) (SSIS) die empfohlene Lösung. Weitere Informationen finden Sie unter SQL Server Integration Services.

  • Wenn Sie Schemaänderungen an einer veröffentlichten Tabelle vornehmen, müssen die benutzerdefinierten Prozeduren neu generiert werden. Weitere Informationen finden Sie unter Erneutes Generieren von Transaktionsprozeduren zur Erfassung von Schemaänderungen.

  • Wenn Sie einen höheren Wert als 1 für den -SubscriptionStreams-Parameter des Verteilungs-Agent verwenden, müssen Sie sicherstellen, dass Aktualisierungen an der Primärschlüsselspalte erfolgreich sind. Beispiel:

    update ... set pk = 2 where pk = 1 -- update 1
    update ... set pk = 3 where pk = 2 -- update 2
    

    Wenn der Verteilungs-Agent mehrere Verbindungen verwendet, werden diese beiden Aktualisierungen gegebenenfalls über verschiedene Verbindungen repliziert. Wird Aktualisierung 1 zuerst angewendet, gibt es kein Problem. Wird Aktualisierung 2 zuerst angewendet, wird '0 Zeilen betroffen' zurückgegeben, da Aktualisierung 1 noch nicht stattgefunden hat. Diese Situation wird von den Standardprozeduren beantwortet. Dabei wird ein Fehler ausgelöst, wenn von einer Aktualisierung keine Zeilen betroffen sind:

    if @@rowcount = 0
        if @@microsoftversion>0x07320000
            exec sys.sp_MSreplraiserror 20598
    

    Das Auslösen des Fehlers zwingt den Verteilungs-Agent, die Aktualisierungen erneut über eine einzige Verbindung zu versuchen. Dieser Versuch ist dann erfolgreich. Benutzerdefinierte gespeicherte Prozeduren müssen eine ähnliche Logik einschließen.

Aufrufsyntax für gespeicherte Prozeduren

Es gibt fünf Optionen für die Syntax, mit der die von der Transaktionsreplikation verwendeten Prozeduren aufgerufen werden:

  • CALL-Syntax. Diese Syntax kann für Einfügungen, Aktualisierungen und Löschungen verwendet werden. Die Replikation verwendet diese Syntax standardmäßig für Einfügungen und Löschungen.

  • SCALL-Syntax. Diese Syntax kann nur für Aktualisierungen verwendet werden. Die Replikation verwendet diese Syntax standardmäßig für Aktualisierungen.

  • MCALL-Syntax. Diese Syntax kann nur für Aktualisierungen verwendet werden.

  • XCALL-Syntax. Diese Syntax kann für Aktualisierungen und Löschungen verwendet werden.

  • VCALL. Diese Syntax wird für aktualisierbare Abonnements verwendet. Nur interner Gebrauch.

Die einzelnen Methoden unterscheiden sich in der Datenmenge, die an den Abonnenten weitergegeben wird. SCALL gibt z. B. Werte nur für die Spalten weiter, die tatsächlich von der Aktualisierung betroffen sind. XCALL dagegen erfordert alle Spalten (unabhängig davon, ob sie von einer Aktualisierung betroffen sind) und alle alten Datenwerte für jede Spalte. In vielen Fällen eignet sich SCALL für Aktualisierungen. Erfordert die Anwendung jedoch alle Datenwerte bei einer Aktualisierung, empfiehlt sich die Verwendung von XCALL.

CALL-Syntax

  • Gespeicherte Prozeduren zu INSERT
    Gespeicherte Prozeduren, die INSERT-Anweisungen verarbeiten, übergeben die in allen Spalten eingefügten Werte:

    c1, c2, c3,... cn
    
  • Gespeicherte Prozeduren zu UPDATE
    Gespeicherte Prozeduren, die UPDATE-Anweisungen verarbeiten, übergeben die aktualisierten Werte für alle in dem Artikel definierten Spaltenwerte, gefolgt von den ursprünglichen Werten der Primärschlüsselspalten (es wird kein Versuch zur Bestimmung der geänderten Spalten unternommen):

    c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn
    
  • Gespeicherte Prozeduren zu DELETE
    Gespeicherte Prozeduren, die DELETE Anweisungen verarbeiten, übergeben die Werte der folgenden Primärschlüsselspalten:

    pkc1, pkc2, pkc3,... pkcn
    

SCALL-Syntax

  • Gespeicherte Prozeduren zu UPDATE
    Gespeicherte Prozeduren, die UPDATE-Anweisungen verarbeiten, übergeben die aktualisierten Werte nur für die geänderten Spalten, gefolgt von den ursprünglichen Werten der Primärschlüsselspalten, auf die wiederum ein Bitmaskenparameter (binary(n)) folgt, der die geänderten Spalten anzeigt. Im folgenden Beispiel wurde die Spalte 2 (c2) nicht geändert:

    c1, , c3,... cn, pkc1, pkc2, pkc3,... pkcn, bitmask
    

MCALL-Syntax

  • Gespeicherte Prozeduren zu UPDATE
    Gespeicherte Prozeduren, die UPDATE-Anweisungen verarbeiten, übergeben die aktualisierten Werte für alle in dem Artikel definierten Spaltenwerte, gefolgt von den ursprünglichen Werten der Primärschlüsselspalten, auf die wiederum ein Bitmaskenparameter (binary(n)) folgt, der die geänderten Spalten anzeigt:

    c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn, bitmask
    

XCALL-Syntax

  • Gespeicherte Prozeduren zu UPDATE
    Gespeicherte Prozeduren, die UPDATE-Anweisungen verarbeiten, übergeben die ursprünglichen Werte (das Anfangsimage) für alle in dem Artikel definierten Spalten, gefolgt von den aktualisierten Werten (das Endimage) für alle in dem Artikel definierten Spalten.

    old-c1, old-c2, old-c3,... old-cn, c1, c2, c3,... cn,
    
  • Gespeicherte Prozeduren zu DELETE
    Gespeicherte Prozeduren, die DELETE-Anweisungen verarbeiten, übergeben die ursprünglichen Werte (das Anfangsimage) für alle in dem Artikel definierten Spalten:

    old-c1, old-c2, old-c3,... old-cn
    
    HinweisHinweis

    Beim Verwenden von XCALL wird erwartet, dass die Anfangsimagewerte für text- und image-Spalten NULL sind.

Beispiele

Bei den folgenden Prozeduren handelt es sich um Standardprozeduren, die für die Vendor-Tabelle in der Adventure Works-Beispieldatenbank erstellt wurden.

--INSERT procedure using CALL syntax
create procedure [sp_MSins_PurchasingVendor] 
  @c1 int,@c2 nvarchar(15),@c3 nvarchar(50),@c4 tinyint,@c5 bit,@c6 bit,@c7 nvarchar(1024),@c8 datetime
as 
begin 
insert into [Purchasing].[Vendor]( 
 [VendorID]
,[AccountNumber]
,[Name]
,[CreditRating]
,[PreferredVendorStatus]
,[ActiveFlag]
,[PurchasingWebServiceURL]
,[ModifiedDate]
 )
values ( 
 @c1
,@c2
,@c3
,@c4
,@c5
,@c6
,@c7
,@c8
 ) 
end
go


--UPDATE procedure using SCALL syntax
create procedure [sp_MSupd_PurchasingVendor] 
 @c1 int = null,@c2 nvarchar(15) = null,@c3 nvarchar(50) = null,@c4 tinyint = null,@c5 bit = null,@c6 bit = null,@c7 nvarchar(1024) = null,@c8 datetime = null,@pkc1 int
,@bitmap binary(2)
as
begin
update [Purchasing].[Vendor] set 
 [AccountNumber] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [AccountNumber] end
,[Name] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Name] end
,[CreditRating] = case substring(@bitmap,1,1) & 8 when 8 then @c4 else [CreditRating] end
,[PreferredVendorStatus] = case substring(@bitmap,1,1) & 16 when 16 then @c5 else [PreferredVendorStatus] end
,[ActiveFlag] = case substring(@bitmap,1,1) & 32 when 32 then @c6 else [ActiveFlag] end
,[PurchasingWebServiceURL] = case substring(@bitmap,1,1) & 64 when 64 then @c7 else [PurchasingWebServiceURL] end
,[ModifiedDate] = case substring(@bitmap,1,1) & 128 when 128 then @c8 else [ModifiedDate] end
where [VendorID] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end
go


--DELETE procedure using CALL syntax
create procedure [sp_MSdel_PurchasingVendor] 
  @pkc1 int
as 
begin 
delete [Purchasing].[Vendor]
where [VendorID] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end 
go