CREATE PROC sp_CopyObject
@S_DatabaseName sysname, --要复制对象的源数据库名
@D_DatabaseName sysname=NULL, --复制对象的目标数据库名,不指定则为当前库名
@TypeList nvarchar(50)=NULL --以逗号分隔的对象类型列表,只能是P/V/TR/IF/TF/FN之一或者是它们的组合.不指定是所有对象
AS
IF DB_ID(@S_DatabaseName) IS NULL
BEGIN
RAISERROR('源数据库 "%s" 不存在',12,16,@S_DatabaseName)
RETURN
END
IF DB_ID(@D_DatabaseName) IS NULL SET @D_DatabaseName=DB_NAME()
DECLARE @sql nvarchar(4000)
--处理对象类型列表
SET @sql=N''
SELECT @sql=@sql+N','+QUOTENAME(xtype,N'''')
FROM(
SELECT xtype=N'P' UNION ALL SELECT N'IF' UNION ALL
SELECT xtype=N'V' UNION ALL SELECT N'TF' UNION ALL
SELECT xtype=N'TR' UNION ALL SELECT N'FN'
)a WHERE CHARINDEX(N','+xtype+N',',N','+@TypeList+N',')>0
IF @@ROWCOUNT=0 OR @sql=''
SET @TypeList='N''P'',N''V'',N''TR'',N''IF'',''TF'',''FN'''
ELSE
SET @TypeList=STUFF(@sql,1,1,N'')
--获取要复制对象(存储,视图,触发器)的数据
CREATE TABLE #(name sysname,xtype char(2),number smallint,colid smallint,text nvarchar(4000))
SET @sql=N'
INSERT #(name,xtype,number,colid,text)
SELECT o.name,o.xtype,m.number,m.colid,m.text
FROM '+QUOTENAME(@S_DatabaseName)+N'.dbo.sysobjects o,'
+QUOTENAME(@S_DatabaseName)+N'.dbo.syscomments m
WHERE o.id=m.id
AND m.encrypted=0
AND o.xtype IN('+@TypeList+N')
AND o.status>=0'
EXEC sp_executesql @sql
DECLARE tb CURSOR LOCAL
FOR
SELECT N'USE '+QUOTENAME(@D_DatabaseName)+N'
DECLARE @name sysname,@number smallint
SELECT @name='+QUOTENAME(name,N'''')+N',
@number='+CAST(number as varchar)+N'
DECLARE @1 nvarchar(4000),@2 nvarchar(4000),@3 nvarchar(4000),@4 nvarchar(1000)
SELECT @1=N'''',@2=N'''',@3=N''''
SELECT @1=@1+N'',@''+RTRIM(colid)+N'' nvarchar(4000)'',
@2=@2+N'',@''+RTRIM(colid)
+N''=CASE colid WHEN ''+RTRIM(colid)
+N'' THEN text ELSE @''+RTRIM(colid)+N'' END'',
@3=@3+N''+@''+RTRIM(colid)
FROM #
WHERE name=@name AND number=@number
ORDER BY colid
SELECT @1=STUFF(@1,1,1,N''''),
@2=STUFF(@2,1,1,N''''),
@3=STUFF(@3,1,1,N''''),
@4=N'' WHERE name=''+QUOTENAME(@name,N'''''''')
+N'' AND number=''+RTRIM(@number)
IF @NUMBER<2 AND EXISTS(SELECT * FROM sysobjects WHERE name=@name AND xtype='
+QUOTENAME(xtype,N'''')+N') DROP '+CASE xtype
WHEN N'P' THEN N'PROC'
WHEN N'V' THEN N'VIEW'
WHEN N'TR' THEN N'TRIGGER'
ELSE N'FUNCTION' END
+N' '+QUOTENAME(name)+N'
EXEC(N''DECLARE ''+@1+''
SELECT ''+@2+'' FROM # ''+@4+N''
EXEC(''+@3+'')'')'
FROM #
GROUP BY name,xtype,number
OPEN tb
FETCH tb INTO @sql
WHILE @@FETCH_STATUS=0
BEGIN
EXEC sp_executesql @sql
FETCH tb INTO @sql
END
CLOSE tb
DEALLOCATE tb
--2. 将tb表中的col1及col2列中的数据合并到col列中,并且在合并的数据前后加上列标识。
--测试数据
CREATE TABLE tb(col text,col1 text,col2 text)
INSERT tb SELECT 'a' ,NULL,'c2'
UNION ALL SELECT NULL,'b2','c2'
UNION ALL SELECT '' ,'b3',NULL
GO
--更新处理
DECLARE @p binary(16),@p1 binary(16),@p2 binary(16)
DECLARE tb CURSOR LOCAL
FOR
SELECT TEXTPTR(col),TEXTPTR(col1),TEXTPTR(col2) FROM tb
OPEN tb
FETCH tb INTO @p,@p1,@p2
WHILE @@FETCH_STATUS=0
BEGIN
IF TEXTVALID('tb.col',@p)=0
BEGIN
UPDATE tb SET col='' WHERE CURRENT OF tb
UPDATE tb SET @p=TEXTPTR(col) WHERE CURRENT OF tb
END
IF TEXTVALID('tb.col1',@p1)=1
BEGIN
UPDATETEXT tb.col @p NULL 0 '<col1>'
UPDATETEXT tb.col @p NULL 0 tb.col1 @p1
UPDATETEXT tb.col @p NULL 0 '</col1>'
END
IF TEXTVALID('tb.col2',@p2)=1
BEGIN
UPDATETEXT tb.col @p NULL 0 '<col2>'
UPDATETEXT tb.col @p NULL 0 tb.col2 @p2
UPDATETEXT tb.col @p NULL 0 '</col2>'
END
FETCH tb INTO @p,@p1,@p2
END
CLOSE tb
DEALLOCATE tb
GO
--显示结果
SELECT * FROM tb
DROP TABLE tb
/*--结果
col col1 col2
-------------------------------------- ----------------------- ----------------------
a<col2>c2</col2> NULL c2
<col1>b2</col1><col2>c2</col2> b2 c2
<col1>b3</col1> b3 NULL
--*/
加上昨天晚上都在研究合并复制的配置。我需要的环境是这样的,服务器端的数据库采用SQL Server 2000.PPC客户端采用的精简数据库是Sql Server Mobile Edition。
时下大多采用的数据库配合方式基本上是sql server 2005和Sql Server Mobile Edition。其实,我也想这样采用。但是考虑到原有的数据库系统是采用2000的版本,很难让原来的研发人员去花费时间整迁移。
本来,精简数据库要选择sql ce 2.0。但在安装过程中总是无法成功解决Server Tool的安装先觉条件。(可能,跟我安装过VS2005或Sql2005有关,中间我还没有时间测试过没有Vs2005和Sql2005干扰下的安装环境。)
如果要和MSsql2000进行合并复制的操作,安装Sql Server Mobile Edition前必须要做的是安装针对MSsql 2000的sp3和针对sqlce的sp3。只有两个补丁都安装了,Sqlce 3.0的安装程序才能检测出sql 2000已经具备复制组件。
当这一步结束后,接下来的创建快照文件夹,创建发布,设置访问权限,安全参数,Web同步向导配置,以及最后的编程测试。都可以参考MSDN中的这篇文章。虽然这篇文章针对的是2005版本,但里面提到的术语和概念在Sql server 2000中都能找到对应的。因此,按部就班就可以。
最后需要注意的是,订阅的步骤可以省略掉不要。在Sql Server 2000 中无法配置符合sql ce的订阅。(至少本人是认为无法配置)。测试是否可以实现合并复制的途径只有编程实现。即编程添加订阅,然后实现同步。
在测试用例程序时,我们可能会碰到异常。捕获异常消息,它如果是提示快照消息过时,需要重新建立快照之类。这个问题在于代理程序的调度设置上有问题。可能这个快照还没有生成,换句话说代理程序还未被调度。解决它,那就是修改调度的参数。为了最好把调度直接设置为1min/次;
至此,这个配置就结束.成功了.同步也正常中.
SQL Server 2005相对于SQL Server 2000来说,无论是性能还是功能都有一个相当大的提高,甚至可以用“革命”来形容这一次升级。SQL Server 2005使 SQL Server 跻身于企业级数据库行列。在数据高可用性方面,SQL Server 2005为用户提供了数据镜像、复制、故障转移群集、日志传送功能。本文向读者简单介绍SQL Server 2005的复制功能。
一、 “复制”简介
复制是将数据或数据库对象从一个数据库复制和分发到另外一个数据库,并进行数据同步,从而使源数据库和目标数据库保持一致。使用复制,可以在局域网和广域网、拨号连接、无线连接和 Internet 上将数据分发到不同位置以及分发给远程或移动用户。
一组SQL Server 2005复制有发布服务器、分发服务器、订阅服服务器(图1:复制服务器之间的关系图)组成,它们之间的关系类似于书报行业的报社或出版社、邮局或书店、读者之间的关系。
试验在同一台机器的二个实例间进行,实例名分别是SERVER01、SERVER02 。将SERVER01配置发布服务器和分发服务器(也就是前面提到的“本地分发服务器”),SERVER02配置为订阅服务器。在本例中将SERVER01中一个DBCoper库中person表作为发布的数据,在发布前请确保person表有主键、SQL SERVER 代理自动启动、发布数据库是日志是完整模式。
至此, SQL SERVER 2005 同步复制就完成了。使用复制技术,用户可以将一份客户端的数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可的范围内共享这份数据。复制技术可以确保分布在不同地点的数据自动同步更新,从而保证数据的一致性,就无需编程实现客户端和服务器端数据同步了!大大提高了工作效率!
--在srv1中创建如下的同步处理存储过程
create proc p_process
as
--更新修改过的数据
update b set name=i.name,telphone=i.telphone
from srv2.库名.dbo.author b,author i
where b.id=i.id and
(b.name <> i.name or b.telphone <> i.telphone)
--插入新增的数据
insert srv2.库名.dbo.author(id,name,telphone)
select id,name,telphone from author i
where not exists(
select * from srv2.库名.dbo.author where id=i.id)
--删除已经删除的数据(如果需要的话)
delete b
from srv2.库名.dbo.author b
where not exists(
select * from author where id=b.id)
go