Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
platí pro:SQL Server
azure 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 (INSERTUPDATEnebo DELETE) rozšířit do 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, UPDATEnebo DELETE příkazu (výchozí hodnota pro uživatele, kteří nejsou SQL Server Odběratelé).
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
Replikace vytváří tři výchozí uložené procedury pro každý článek tabulky:
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 článek přidáte do publikace a zda databáze předplatného obsahuje tabulku se stejným názvem, ale s jiným vlastníkem.
Každý z těchto postupů můžete nahradit vlastním postupem, který určíte při přidávání článku do publikace. Použijte vlastní postupy, pokud vaše aplikace vyžaduje vlastní logiku, například vkládání dat do auditní tabulky při aktualizaci řádku u odběratele. Další informace o zadání vlastních uložených procedur naleznete v návodech uvedených v předchozí části.
Když určujete buď výchozí replikační procedury, nebo vlastní procedury, určujete také syntaxi volání pro každou proceduru. Replikace vybírá výchozí syntaxi hovoru, pokud používáte výchozí procedury. 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. Pro více informací viz sekce "Syntax volání pro uložené procedury" v tomto článku.
Úvahy při 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:
Musíte podporovat logiku v uložené procedurě; Microsoft neposkytuje podporu pro vlastní logiku.
Aby se předešlo konfliktům s transakcemi používanými replikací, nepoužívejte explicitní transakce v vlastních procedurách.
Schéma u Subscriber je obvykle totožné se schématem v Publisher, ale může být také podmnožinou schématu Publisher, pokud používáte filtrování sloupců. Pokud potřebujete schéma transformovat při pohybu dat tak, aby schéma u Subscriber nebylo podmnožinou schématu na Publisher, použijte SQL Server 2019 Integration Services (SSIS). Další informace naleznete v tématu Služby Integrace SQL Serveru.
Pokud provedete změny schématu v publikované tabulce, znovu vygenerujte vlastní procedury. Další informace naleznete v tématu opětovné vygenerování vlastních transakčních procedur, aby odrážely změny schématu.
Pokud použijete hodnotu větší než 1 pro parametr -SubscriptionStreams v Distribution Agent, ujistěte se, že aktualizace sloupců primárního klíče jsou úspěšné. Například:
update ... set pk = 2 where pk = 1 -- update 1 update ... set pk = 3 where pk = 2 -- update 2Pokud Distribution Agent používá více než jedno připojení, tyto dvě aktualizace se mohou replikovat přes různá připojení. Pokud je aktualizace 1 aplikována jako první, není problém. Pokud je aktualizace 2 aplikována jako první, vrátí se
0 rows affected, protože aktualizace 1 ještě neproběhla. Výchozí postupy tuto situaci řeší tak, že vyvolají chybu, pokud při aktualizaci nejsou ovlivněny žádné řádky:if @@rowcount = 0 if @@microsoftversion>0x07320000 exec sys.sp_MSreplraiserror 20598Vyvolání této chyby přinutí agenta Distribution Agent zopakovat aktualizace pomocí jediného připojení, což se podaří. Vlastní uložené procedury musí obsahovat podobnou logiku.
Syntaxe volání pro uložené procedury
Můžete použít pět různých syntaktických možností k označení postupů, které transakční replikace používá:
Syntaxe volání. Tuto syntaxi používejte pro vkládání, aktualizace a mazání. Ve výchozím nastavení používá replikace tuto syntaxi pro vkládání a odstraňování.
Syntaxe SCALL Tuto syntaxi používejte pouze pro aktualizace. Ve výchozím nastavení používá replikace tuto syntaxi pro aktualizace.
Syntaxe MCALL Tuto syntaxi používejte pouze pro aktualizace.
Syntaxe XCALL Použijte tuto syntaxi pro aktualizace a mazání.
VCALL. Použijte tuto syntaxi pro aktualizovatelné předplatné. Pouze interní použití.
Každá metoda se liší množstvím dat, která odesílá odběrateli. Například SCALL předává hodnoty pouze pro sloupce, které aktualizace skutečně ovlivňuje. XCALL vyžaduje všechny sloupce, ať už je aktualizace ovlivní 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 tuto potřebu podporuje.
Syntaxe VOLÁNÍ
INSERT uložené procedury
Uložené procedury, které zpracovávají INSERT příkazy, přijímají vložené hodnoty pro všechny sloupce:
c1, c2, c3,... cn
UPDATE uložené procedury
Uložené procedury, které zpracovávají UPDATE příkazy, obdrží aktualizované hodnoty pro všechny sloupce definované v článku, následované původními hodnotami pro sloupce primárních klíčů. Proces se nesnaží určit, které sloupce se změnily:
c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn
DELETE uložené procedury
Uložené procedury, které zpracovávají DELETE příkazy, přijímají hodnoty pro sloupce primárního klíče:
pkc1, pkc2, pkc3,... pkcn
Syntaxe SCALL
UPDATE uložené procedury
Uložené procedury, které zpracovávají UPDATE příkazy, přijímají aktualizované hodnoty pouze pro ty sloupce, které se změnily, následované původními hodnotami pro sloupce primárního klíče a následně parametr bitmask (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
UPDATE uložené procedury
Uložené procedury, které zpracovávají UPDATE příkazy, obdrží aktualizované hodnoty pro všechny sloupce definované v článku, následované původními hodnotami sloupců primárního klíče a poté parametr bitmask (binary(n)), který označuje změněné sloupce:
c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn, bitmask
Syntaxe XCALL
UPDATE uložené procedury
Uložené procedury, které zpracovávají příkazy UPDATE, obdrží původní hodnoty (před změnou) pro všechny sloupce definované v publikaci a poté aktualizované hodnoty (po změně) pro všechny sloupce definované v publikaci:
old-c1, old-c2, old-c3,... old-cn, c1, c2, c3,... cn,
DELETE uložené procedury
Uložené procedury, které zpracovávají DELETE příkazy, dostávají původní hodnoty (obrázek před) pro všechny sloupce definované v článku:
old-c1, old-c2, old-c3,... old-cn
Poznámka
Když použijete XCALL, hodnoty před obrázkem pro text a image sloupce by měly být 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