Sdílet prostřednictvím


Transakční články – Určení způsobu šíření změn

platí pro:SQL Serverazure SQL Managed Instance

Transakční replikace umožňuje určit, jak se změny dat šíří z Publisheru na odběratele. Pro každou publikovanou tabulku můžete zadat jeden ze čtyř způsobů, jak se má každá operace (INSERT, UPDATE nebo DELETE) rozšířit na odběratele:

  • Určete, že transakční replikace by měla skriptovat a následně volat uloženou proceduru, která provede změny k odběratelům (výchozí).

  • Určete, že by se změna měla rozšířit pomocí příkazu INSERT, UPDATE nebo DELETE (výchozí hodnota pro předplatitele jiného systému než SQL Server).

  • Určete, že se má použít vlastní uložená procedura.

  • Určete, že by tato akce neměla být provedena u žádného odběratele. Transakce tohoto typu se nereplikují.

Ve výchozím nastavení transakční replikace šíří změny odběratelům prostřednictvím sady uložených procedur, které jsou nainstalovány pro každého odběratele. Když v tabulce v Publisheru dojde k vložení, aktualizaci nebo odstranění, operace je přeměněna na volání uložené procedury na Subscriberu. Uložená procedura přijímá parametry, které se mapují na sloupce v tabulce, což umožňuje jejich změny u odběratele.

Chcete-li nastavit metodu šíření pro změny dat u transakčních článků, přečtěte si Nastavení metody šíření pro změny dat u transakčních článků.

Výchozí a vlastní uložené procedury

Tři postupy, které replikace vytvoří ve výchozím nastavení pro každý článek tabulky, jsou:

  • sp_MSins_<název tabulky>, který zpracovává vkládání.

  • sp_MSupd_<název tabulky>, který zpracovává aktualizace.

  • sp_MSdel_<název tabulky>, který zpracovává odstranění.

Název tabulky <> použitý v postupu závisí na tom, jak byl článek přidán do publikace a jestli databáze odběru obsahuje tabulku se stejným názvem s jiným vlastníkem.

Každý z těchto postupů lze nahradit vlastním postupem, který zadáte při přidávání článku do publikace. Vlastní postupy se používají, pokud aplikace vyžaduje vlastní logiku, například vložení dat do tabulky auditu při aktualizaci řádku u Odběratele. Další informace o zadávání vlastních uložených procedur najdete v tématech z oddílu „Jak na to“ uvedených výše.

Pokud zadáte výchozí postupy replikace nebo vlastní procedury, zadáte také syntaxi volání pro jednotlivé procedury (pokud použijete výchozí postupy, vybere replikace výchozí hodnoty). Syntaxe volání určuje strukturu parametrů zadaných pro postup a množství informací odesílaných odběrateli s každou změnou dat. Další informace najdete v části "Syntaxe volání pro uložené procedury" v tomto tématu.

Důležité informace o používání vlastních uložených procedur

Při používání vlastních uložených procedur mějte na paměti následující skutečnosti:

  • Logiku musíte podporovat v uložené proceduře; Microsoft neposkytuje podporu pro vlastní logiku.

  • Aby nedocházelo ke konfliktům s transakcemi používanými replikací, neměly by se explicitní transakce používat ve vlastních procedurách.

  • Schéma odběratele je obvykle stejné jako schéma v Publisheru, ale může být také podmnožinou schématu vydavatele, pokud se používá filtrování sloupců. Pokud ale potřebujete transformovat schéma při přesunu dat tak, aby schéma pro odběratele nebylo podmnožinou schématu v Publisheru, doporučuje se SQL Server 2019 Integration Services (SSIS). Další informace naleznete v tématu SQL Server Integration Services.

  • Pokud provedete změny schématu v publikované tabulce, musí se vlastní postupy znovu vygenerovat. Další informace naleznete v tématu opětovné vygenerování vlastních transakčních procedur, aby odrážely změny schématu.

  • Pokud pro -SubscriptionStreams parametr distribučního agenta použijete hodnotu větší než 1, musíte zajistit, aby aktualizace sloupců primárního klíče byly úspěšné. Například:

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

    Pokud distribuční agent používá více než jedno připojení, můžou se tyto dvě aktualizace replikovat přes různá připojení. Pokud se nejprve použije aktualizace 1, není problém; Pokud je aktualizace 2 použita jako první, vrátí hodnotu 0 řádků ovlivněných, protože aktualizace 1 ještě nenastala. Tato situace se zpracovává ve výchozích postupech vyvoláním chyby, pokud nejsou v aktualizaci ovlivněny žádné řádky:

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

    Vyvolání chyby donutí distribučního agenta opakovat aktualizace přes jedno připojení, což se podaří. Vlastní uložené procedury musí obsahovat podobnou logiku.

Syntaxe volání pro uložené procedury

Syntaxe používaná k volání procedur používaných transakční replikací má pět možností:

  • Syntaxe volání. Lze použít pro vložení, aktualizace a odstranění. Ve výchozím nastavení používá replikace tuto syntaxi pro vkládání a odstraňování.

  • Syntaxe SCALL Lze použít pouze pro aktualizace. Ve výchozím nastavení používá replikace tuto syntaxi pro aktualizace.

  • Syntaxe MCALL Lze použít pouze pro aktualizace.

  • Syntaxe XCALL Lze použít pro aktualizace a odstranění.

  • VCALL. Používá se pro aktualizovatelná předplatná. Pouze interní použití.

Každá metoda se liší v množství dat, která se rozšíří na odběratele. Například SCALL předává hodnoty pouze pro sloupce, které jsou skutečně ovlivněny aktualizací. XCALL naproti tomu vyžaduje všechny sloupce (ať už ovlivněné aktualizací nebo ne) a všechny staré datové hodnoty pro každý sloupec. V mnoha případech je SCALL vhodný pro aktualizace, ale pokud vaše aplikace vyžaduje všechny datové hodnoty během aktualizace, XCALL to umožňuje.

Syntaxe VOLÁNÍ

Procedury uložené pro INSERT
Uloženým procedurám, které zpracovávají příkazy INSERT, budou předávány vložené hodnoty pro všechny sloupce:

c1, c2, c3,... cn  

AKTUALIZACE uložených procedur
Uložené procedury, které zpracovávají příkazy UPDATE, budou předány aktualizované hodnoty pro všechny sloupce definované v článku, za kterými následují původní hodnoty sloupců primárního klíče (nepokouší se určit, které sloupce byly změněny.):

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

Smazat uložené procedury
Uložené procedury zpracovávající příkazy DELETE budou předány hodnoty pro sloupce primárního klíče:

pkc1, pkc2, pkc3,... pkcn  

Syntaxe SCALL

AKTUALIZACE uložených procedur
Uložené procedury zpracovávající příkazy UPDATE budou mít předané aktualizované hodnoty pouze pro sloupce, které se změnily, následované původními hodnotami pro sloupce primárního klíče a dále následovanou bitovou maskou (binary(n)), která označuje změněné sloupce. V následujícím příkladu se sloupec 2 (c2) nezměnil:

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

Syntaxe MCALL

AKTUALIZACE uložených procedur
Uložené procedury, které zpracovávají příkazy UPDATE, budou předány aktualizované hodnoty pro všechny sloupce definované v článku, následovány původními hodnotami sloupců primárního klíče, poté následuje parametr bitové masky (binary(n)), který označuje změněné sloupce.

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

Syntaxe XCALL

AKTUALIZACE uložených procedur
Uložené procedury zpracovávající příkazy UPDATE budou předány původní hodnoty (před obrázkem) pro všechny sloupce definované v článku, následované aktualizovanými hodnotami (následující obrázek) pro všechny sloupce definované v článku:

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

Odstranit uložené procedury
Uložené procedury zpracovávající příkazy DELETE budou předány původní hodnoty (před obrázkem) pro všechny sloupce definované v článku:

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

Poznámka

Při použití XCALL se očekává, že hodnoty předchozího obrazu pro text a obraz sloupců budou NULL.

Příklady

Následující postupy jsou výchozí postupy vytvořené pro Vendor Table v ukázkové databázi 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