MSSQL中存储过程XXX_msrepl_ccs的作用

在事务复制里,如果一个article被更新,distributionagent会调用相应的存储过程将数据更新到订阅端。 这些存储过程分别是[sp_MSins_dboTableName],[sp_MSdel_dboTableName]和 [sp_MSupd_dboTableName],分别对应插入,删除和更新操作。这些存储过程是在快照初始化时创建的。不过您可能曾经观察到还有其它两个存储过程被调用过:sp_MSins_dboTableName_msrepl_ccs,sp_MSdel_dboTableName_msrepl_ccs。
那么两个存储过程的作用是什么呢?
&">nbsp;
当sp_addpublication 的参数sync_method值为concurrent时,生成快照时article是允许被更新的,这些更新随后也会被应用到订阅端。 如果是使用默认的命令去更新,那么就可能遇到下面的情况:
假设表ta有2行数据,snapshot agent已经读取第一行和第二行数据,这时插入了第三条数据。接下来snapshot会去读第三条数据,并将三行数据打包到bcp文件中。而第三条数据的日志也会被logreader传递到分发。 这样就会产生一个问题:如果仍然使用sp_MSins_dboTableName,就会造成主键冲突,出现1033错误:Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls. 
 
为了避免这种情况,设计出了另外两种存储过程(存储过程的定义请见文章结尾):
当操作是更新时,先判断改行是否存在,如果存在,则使用更新操作。
如果是删除操作,即使影响行为0,也不会抛出20598错误The row was not found at the Subscriber when applying the replicated command。
如果是更新操作,则会先调用css的删除操作,然后调用css的插入命令,以避免20598错误。
所以在初始化的阶段,你会看到多出了两种存储过程。不过在初始化完成后,这两个存储过程就会从订阅段删除掉。
 
下面列出了三个命令的调用截图。 请注意,这类msrepl_ccs的类型有别于普通的存储过程,其值为-2147483618。
 
插入操作。sp_MSins_dboTableName会被解释成sp_MSins_dboTableName_msrepl_ccs。

更新操作。sp_MSupd_dboTableName会分解为两个操作,现将数据删除,然后插入新的数据。

删除操作。sp_MSdel_dboTableName会被解释成sp_MSdel_dboTableName_msrepl_ccs。

存储过程的定义
create procedure [dbo].[sp_MSins_dbota_msrepl_ccs]
@c1 int,
@c2 int
as
begin
if exists (select *
             from [dbo].[ta]
            where [id] = @c1)---------在普通的存储过程中,是没有这段判断逻辑的。
begin
update [dbo].[ta] set
[c] = @c2
where [id] = @c1
end
else
begin
insert into [dbo].[ta](
[id],
[c]
) values (
    @c1,
    @c2    )
end
end
go
create procedure [dbo].[sp_MSdel_dbota_msrepl_ccs]
@pkc1 int
as
begin 
delete [dbo].[ta]
where [id] = @pkc1
---------在普通的存储过程中,还有一段额外的逻辑: 如果影响行为0,则抛出异常。
end 
go

时间: 2024-08-20 23:09:29

MSSQL中存储过程XXX_msrepl_ccs的作用的相关文章

在MSSQL中实现Sequence功能

目的: 通过该功能取代 MSSQL 中的表ID列自动递增功能   主题一:如何通过Sequence名得到一个Sequence值 方法: 1.    创建一个表Sequence,保存Sequence的值 2.    创建一个存储过程GetNextSequence,以通过它得到下一个Sequence 主题二:如何通过一个表名得到一个Sequence值 1.    创建一个表TableSequence,保存表中的列对应的是哪个Sequence 2.    创建一个存储过程CreateTableSeq,

MSSQL自身存储过程的一个注入漏洞_漏洞研究

Infos: MSSQL自身存储过程的一个注入 Author: 疯子[BCT] Date: 10/11/2007 我看到MSSQL的存储过程中,有模有样的在过滤. 然后我就去读读他们的存储过程.就找到了一个注入而已. 疯子如是说. 漏洞资料如下: master..sp_resolve_logins存储过程中,对@dest_path参数过滤不严,导致xp_cmdshell注入. 分析: 复制代码 代码如下: SELECT @dest_path = RTRIM(LTRIM(@dest_path)) 

二种MSSQL分页存储过程实例应用

二种MSSQL分页存储过程实例应用 <html xmlns="http://www.111cn.net/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>二种MSSQL分页存储过程实例应用</title> </head> <b

settings-orcal 中存储过程 这样写对吗

问题描述 orcal 中存储过程 这样写对吗 create or replace procedure PageList(tbName IN VARCHAR(255),tbFieldsIN VARCHAR(1000), orderField IN VARCHAR(255),orderType IN INT,strWhere IN VARCHAR(1000),pageSize IN INT,pageIndex IN INT,pageRecord OUT INT) is BEGIN /*定义变量*/

细细研究MySql中delimiter起到的作用

MySql中delimiter究竟可以起到些什么作用呢?可能不少人都有这样的疑惑,下文就为您介绍MySql中delimiter的作用,供您参考. MYSQL导出一个SQL后: DELIMITER $$      DROP TRIGGER IF EXISTS `updateegopriceondelete`$$      CREATE          TRIGGER `updateegopriceondelete` AFTER  DELETE ON  `customerinfo`        

.NET数据库应用程序中存储过程的应用

程序|存储过程|数据|数据库 一.前言: 存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中.用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它.存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程.总的来说,存储过程具有以下一些优点: ◆存储过程允许标准组件式编程. ◆存储过程能够实现较快的执行速度. ◆存储过程能够减少网络流量. ◆存储过程可被作为一种安全机制来充分利用. 本文作者将向大

php 调用mssql 2000存储过程代码

  php 调用mssql 2000存储过程代码这是我昨天做出来了哦,下面我们先看看利用php调用mssql的存储过程的代码吧 $start = isset($_GET['start'])?$_GET['start']:0; $end = isset($_GET['end'])?$_GET['end']:0; $pagesize = isset($_GET['pagesize'])?$_GET['pagesize']:0; $stmt = mssql_init("Bigdatabase"

JAVA中toString方法的作用

以下是对在JAVA中toString方法的作用进行了详细的分析介绍,需要的朋友可以参考下   因为它是Object里面已经有了的方法,而所有类都是继承Object,所以"所有对象都有这个方法". 它通常只是为了方便输出,比如System.out.println(xx),括号里面的"xx"如果不是String类型的话,就自动调用xx的toString()方法 总而言之,它只是sun公司开发java的时候为了方便所有类的字符串操作而特意加入的一个方法  回答补充:写这个

jQuery:delegate中select()不起作用的解决方法

 本篇文章只要是对jQuery:delegate中select()不起作用的解决方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 jQuery有一个很好用的delegate(事件委派)功能,可以给当前以及将来(动态添加)的元素绑定一个事件处理函数.   比如下面的例子,动态添加一个输入文本框后,我想让所有文本框(不管是不是动态添加的)在获取焦点时,自动转大写.   代码如下: <!doctype html> <html> <head>     <