Transactionele artikelen - specificeer hoe veranderingen worden doorgegeven

van toepassing op:SQL ServerAzure SQL Managed Instance

Met transactionele replicatie kunt u opgeven hoe gegevenswijzigingen van publisher worden doorgegeven aan abonnees. Voor elke gepubliceerde tabel kunt u een van de vier manieren opgeven waarop elke bewerking (INSERT, UPDATEof DELETE) moet worden doorgegeven aan de abonnee:

  • Geef op dat transactionele replicatie een script moet uitvoeren en vervolgens een opgeslagen procedure moet aanroepen om wijzigingen door te geven aan abonnees (de standaardinstelling).

  • Geef op dat de wijziging moet worden doorgegeven met behulp van een INSERT, UPDATEof DELETE instructie (de standaardinstelling voor niet-SQL Server abonnees).

  • Geef op dat een aangepaste opgeslagen procedure moet worden gebruikt.

  • Geef op dat deze actie niet moet worden uitgevoerd bij een abonnee. Transacties van dat type worden niet gerepliceerd.

Transactionele replicatie geeft standaard wijzigingen door aan abonnees via een set opgeslagen procedures die op elke abonnee zijn geïnstalleerd. Wanneer een invoeg-, bijwerk- of verwijderbewerking plaatsvindt in een tabel in Publisher, wordt de bewerking omgezet in een aanroep naar een opgeslagen procedure bij de abonnee. De opgeslagen procedure accepteert parameters die zijn toegewezen aan de kolommen in de tabel, zodat deze kolommen kunnen worden gewijzigd bij de abonnee.

Zie De doorgiftemethode instellen voor gegevenswijzigingen in transactionele artikelenals u de doorgiftemethode wilt instellen voor gegevenswijzigingen in transactionele artikelen.

Standaard en aangepaste opgeslagen procedures

Replicatie maakt drie standaard opgeslagen procedures voor elk tabelartikel:

  • sp_MSins_<tabelnaam>, waarmee invoegingen worden afgehandeld.

  • sp_MSupd_<tabelnaam>, waarmee updates worden verwerkt.

  • sp_MSdel_<tabelnaam>, waarmee verwijderingen worden verwerkt.

De <tabelnaam> die in de procedure wordt gebruikt, hangt af van hoe je het artikel aan de publicatie toevoegt en of de abonnementsdatabase een tabel met dezelfde naam maar een andere eigenaar bevat.

Je kunt elk van deze procedures vervangen door een aangepaste procedure die je specificeert bij het toevoegen van een artikel aan een publicatie. Gebruik aangepaste procedures als uw applicatie aangepaste logica vereist, zoals het invoegen van gegevens in een audittabel wanneer een rij wordt bijgewerkt bij een abonnee. Voor meer informatie over het specificeren van aangepaste opgeslagen procedures, zie de how-to-artikelen in de vorige sectie.

Wanneer je ofwel de standaard replicatieprocedures of aangepaste procedures specificeert, specificeer je ook de aanroepsyntaxis voor elke procedure. Replicatie selecteert de standaard aanroepsyntaxis als je de standaardprocedures gebruikt. De aanroepsyntaxis bepaalt de structuur van de parameters die aan de procedure worden verstrekt en hoeveel informatie wordt verzonden naar de abonnee bij elke wijziging van de gegevens. Voor meer informatie, zie de sectie "Call Syntax for Stored Procedures" in dit artikel.

Overwegingen bij het gebruik van aangepaste opgeslagen procedures

Houd rekening met de volgende overwegingen bij het gebruik van aangepaste opgeslagen procedures:

  • Je moet de logica in de opgeslagen procedure ondersteunen; Microsoft biedt geen ondersteuning voor aangepaste logica.

  • Om conflicten met de door replicatie gebruikte transacties te voorkomen, gebruik geen expliciete transacties in aangepaste procedures.

  • Het schema bij de Subscriber is meestal identiek aan het schema bij de Publisher, maar het kan ook een subset zijn van het Publisher-schema als je kolomfiltering gebruikt. Als je het schema moet transformeren terwijl de data verplaatst zodat het schema bij de abonnee geen subset is van het schema bij de Publisher, gebruik dan SQL Server 2019 Integration Services (SSIS). Zie SQL Server Integration Servicesvoor meer informatie.

  • Als je schemawijzigingen aanbrengt in een gepubliceerde tabel, genereer dan de aangepaste procedures opnieuw. Zie Aangepaste transactionele procedures opnieuw genereren om schemawijzigingen weer te gevenvoor meer informatie.

  • Als je een waarde groter dan 1 gebruikt voor de -SubscriptionStreams-parameter van de Distribution Agent, zorg er dan voor dat updates van primaire sleutelkolommen slagen. Bijvoorbeeld:

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

    Als de Distribution Agent meer dan één verbinding gebruikt, kunnen deze twee updates over verschillende verbindingen worden gerepliceerd. Als update 1 als eerste wordt toegepast, is er geen probleem. Als update 2 als eerste wordt toegepast, komt deze terug 0 rows affected omdat update 1 nog niet heeft plaatsgevonden. De standaardprocedures lossen deze situatie aan door een foutmelding te geven als er geen rijen worden beïnvloed bij een update:

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

    Door de fout te genereren, wordt de Distribution Agent gedwongen de updates opnieuw via één verbinding uit te voeren, wat vervolgens lukt. Aangepaste opgeslagen procedures moeten vergelijkbare logica bevatten.

Oproepsyntaxis voor opgeslagen procedures

Je kunt vijf verschillende syntaxisopties gebruiken om de procedures aan te roepen die transactionele replicatie gebruikt:

  • CALL-syntaxis. Gebruik deze syntaxis voor inserts, updates en deletes. Bij replicatie wordt deze syntaxis standaard gebruikt voor invoegingen en verwijderingen.

  • SCALL-syntaxis. Gebruik deze syntaxis alleen voor updates. Bij replicatie wordt deze syntaxis standaard gebruikt voor updates.

  • MCALL-syntaxis. Gebruik deze syntaxis alleen voor updates.

  • XCALL-syntaxis. Gebruik deze syntaxis voor updates en verwijderingen.

  • VCALL. Gebruik deze syntaxis voor updateerbare abonnementen. Alleen intern gebruik.

Elke methode verschilt in de hoeveelheid data die naar de abonnee wordt gestuurd. SCALL geeft bijvoorbeeld alleen waarden door voor de kolommen die een update daadwerkelijk beïnvloedt. XCALL vereist alle kolommen, ongeacht of een update ze beïnvloedt of niet, en alle oude datawaarden voor elke kolom. In veel gevallen is SCALL geschikt voor updates, maar als uw applicatie alle datawaarden tijdens een update vereist, ondersteunt XCALL deze behoefte.

Oproep syntaxis

INSERT opgeslagen procedures
Opgeslagen procedures die INSERT-instructies verwerken, ontvangen de ingevoegde waarden voor alle kolommen:

c1, c2, c3,... cn  

UPDATE opgeslagen procedures
Opgeslagen procedures die UPDATE-instructies verwerken, ontvangen de bijgewerkte waarden voor alle kolommen die in het artikel zijn gedefinieerd, gevolgd door de oorspronkelijke waarden voor de kolommen van de primaire sleutel. Het proces probeert niet te bepalen welke kolommen zijn veranderd:

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

DELETE opgeslagen procedures
Opgeslagen procedures die instructies van het type DELETE verwerken, krijgen waarden voor de primaire sleutelkolommen:

pkc1, pkc2, pkc3,... pkcn  

SCALL-syntaxis

UPDATE opgeslagen procedures
Opgeslagen procedures die UPDATE-instructies verwerken, ontvangen alleen de bijgewerkte waarden voor de kolommen die zijn gewijzigd, gevolgd door de oorspronkelijke waarden voor de primaire-sleutelkolommen en vervolgens een bitmaskerparameter (binary(n)) die aangeeft welke kolommen zijn gewijzigd. In het volgende voorbeeld veranderde kolom 2 (c2) niet:

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

MCALL-syntaxis

UPDATE opgeslagen procedures
Opgeslagen procedures die statements afhandelen UPDATE , ontvangen de bijgewerkte waarden voor alle kolommen die in het artikel zijn gedefinieerd, gevolgd door de oorspronkelijke waarden voor de primaire sleutelkolommen, en vervolgens een bitmask (binary(n)) parameter die de gewijzigde kolommen aangeeft:

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

XCALL-syntaxis

UPDATE opgeslagen procedures
Stored procedures die statements behandelen UPDATE , ontvangen de oorspronkelijke waarden (de voor-afbeelding) voor alle kolommen die in het artikel zijn gedefinieerd, gevolgd door de bijgewerkte waarden (de na-afbeelding) voor alle kolommen die in het artikel zijn gedefinieerd:

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

DELETE opgeslagen procedures
Opgeslagen procedures die DELETE-instructies verwerken, ontvangen de oorspronkelijke waarden (de oude waarden) voor alle kolommen die in de publicatie zijn gedefinieerd:

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

Notitie

Wanneer je XCALL gebruikt, moeten de before-imagewaarden voor de kolommen text en imageNULL zijn.

Voorbeelden

De volgende procedures zijn de standaardprocedures die zijn gemaakt voor de Vendor Table in de voorbeelddatabase Adventure Works.

--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