RDA实现SQL CE与SQL Server间数据存取
PPC程序与桌面PC进行通信的编程方式目前有两种,1、利用Socket编程与桌面程序进行通信;2、利用RDA和Replication(复制)进行数据库编程来完成与桌面SQL Server数据库的存取。利用Socket编程实际上就是通过TCP/IP协议与桌面PC进行通信,它可以很方便的传输一般类型的数据,譬如:字符串、整数以及字节等,但是如果需要传输类型化的数据则需要程序员自己去封装,而且若想由智能设备从桌面数据库引擎中返回指定数据库表的数据,必须编写桌面接口服务程序来查询数据并将结果通过Socket返回给智能设备。那么如何才能在Pocket PC上做到像在桌面PC上一样存取本地数据库甚至是远程桌面PC的数据库呢?通过在智能设备Pocket PC上运行的SQL Server CE 我们便可以轻松存取放置在Pocket PC上的SQL Server CE数据库,还可以通过SQL Server CE中的RDA或者合并复制快速实现从智能设备上存取远程桌面SQL Server2000的数据库
什么叫RDA
远程数据访问,即Remote Data Access(简称为RDA),这项技术在Windows CE2.11版本时已经存在,在SQL Server 2000 For CE 出现后,它的功能便更加丰富了,通过使用这项技术。并利用各种网络环境,用户可以将Pocket PC 连接到远程SQL Server 2000 数据库。如果拥护是第一次进行连接,则移动设备会从SQL Server 2000 上下载需要查询的数据;如果不是第一次查询,移动设备则会对比本地数据库和远程数据库中的内容。并更新远程数据库中的信息。
RDA技术的数据传递。
通过RDA 技术,可以完成以下几种类型的数据传递:
从服务器端下载数据。当移动设备上的本地数据库无内容时,可以通过RDA技术从远程SQL Server 2000服务器下载初始化数据到本地SQL Server CE数据库。例如,应用程序利用RDA技术下载终端拥护登陆数据和产品原始数据到本地移动数据库中,从而完成系统的初始化。如果没有这个最初的初始化步骤,系统将无法登陆。
向服务器上传数据。移动设备上的应用程序在初始化后能够让操作员登陆并使用系统。操作员录入和采集信息(如GPS的信息和条形码的信息)都将被保存在移动数据库中,此时,有可以利用RDA技术将本地数据上传到SQL Server 2000服务器端。值得注意的是,我们在设计服务器端数据库时,在参加同步的表中不能存在自增量字段,否则容易造成上传数据失败,起原因是不同的移动设备回对表中的同一个字段做自增。
更新服务器端数据。有的时候,在多个移动设备上的数据库和服务器端的数据库中都可能存在同一条记录,这时服务器的记录将以最后一次同步移动设备中的记录为准。
下达无返回的T—SQL命令操作远程服务器(Submit SQL)。在移动设备上的应用程序能够利用T-SQL命令远程操作SQL Server 2000数据库。这项功能非常实用,我们通常需要在采集数据时记录当前时间,但是如果存在多个移动设备时,各个移动设备的机器时间又可能是不统一,对这种情况的解决方案就是在每次数据同步时,利用Submit SQL技术刷新服务器时间,下载这个时间并同时设定为移动设备的时间。
SQL Server CE 架构图 如图 所示。
Pull(拉数据)
拉数据就是Windows CE 从SQL Server 服务器获取数据的过程,这里也可以理解从服务器中下载数据。用户不必关心这之间的处理过程,只需要调用ISSCERDA接口的pull方法即可。Pull方法的定义如下:
Virtual /* [id] */ HRESULT STSMETHODCALLTYPY Pull(
/* [in] */ BSTR LocalTableName,
/* [in] */ BSTR SQLSelectString,
/* [in] */BSTR OLEDBConnectionString,
/* [defaultvalue][in] */ RDA_TRACKOPTION TrackOption
/* [defaultvalue][in] */BSTR ErrorTableName)=0;
参数 | 说明 |
LocalTableName | 将从服务器获取数据存储到此表中。如果此表已经存在,将会发生错误。 |
SQLSelectString | 表示从服务器获取数据的SQL表达式,它将控制从服务器取得什么数据。同时也支持那些返回结果集的存储过程和视图。如果是将服务器中的多个表的数据传递到CE中的一个表,那么应将TRACKOPTION的参数值设置成为TRACKINGOFF,表示获取后的数据不能再上传到服务器。 |
OLEDBConnectionString | 连接到SQL Server服务器的连接字符串 |
RDA_TRACKOPTION | 表示SQL Serve CE是否跟踪存储获取服务器数据的表(LocalTableName)的变化。它取值是一个枚举值,具有如表 所示的四个取值。 |
ErrorTableName | 表示CE本地错误表名。在以后调用Push方法向服务器提交变化数据时。如果发生错误,此错误表将被创建,并被写入错误信息。如果调用Pull方法时,此错误表已经存在,将会发生错误。 |
表 参数TrackOption的取值
常量 | 值 | 说明 |
TRACKINGON | 1 | 对于接收到数据的表,SQL Serve CE将跟踪所有的变化,主键约束将根据SQLSelectString被执行而被创建。此值是默认值。 |
TRACKINGOFF | 0 | 对于接收到数据的表,SQL Serve CE将不跟踪所有的变化,主键约束在本地表中也是不会被创建 |
TRACKINGON_INDEXES | 2 | 对于接收到数据的表,SQL Serve CE将跟踪所有的变化,索引和主键如果已经在SQL Server表中存在,并且字段被指定在SQLSelectString查询语句里,那么服务器表中的索引和主键将创建到CE本地表中。 |
TRACKINGOFF_INDEXES | 3 | 对于接收到数据的表,SQL Serve CE将不跟踪所有的变化,索引和主键如果已经在SQL Server表中存在,并且字段被指定在SQLSelectString查询语句里,那么服务器表中的索引和主键将创建到CE本地表中。 |
Push(推数据)
推数据和拉数据是完全相反的两个方法。推数据则是将CE本地库中的数据上传到服务器中。Push方法的定义如下:
Virtual /* [id] */ HRESULT STSMETHODCALLTYPY Push(
/* [in] */ BSTR LocalTableName,
/* [in] */BSTR OLEDBConnectionString,
/* [defaultvalue][in] */ RDA_BATCHOPTION BatchOption)=0;
参数 | 说明 |
LocalTableName | 表示将向服务器上传的变化数据的表名 |
OLEDBConnectionString | 为连接到SQL Server服务器的连接字符串 |
RDA_BATCHOPTION | 表示上传数据的方法。它取值是一个枚举值,具有如表 所示的两个取值。 |
表 参数BatchOption的取值
常量 | 值 | 说明 |
BATCHINGOFF |
| 上传的数据被一条一条更新到服务器 |
BATCHINGON |
| 上传的数据被一次性的更新到服务器 |
Submit(远程T-SQL操作)
Submit方法可以执行远程SQL语句,也就是可以将SQL语句传递到服务器上直接执行,其定义如下:
Virtual /* [id] */ HRESULT STSMETHODCALLTYPY Submit(
/* [in] */ BSTR SQLString,,
/* [in] */BSTR OLEDBConnectionString,)=0;
属性 | 说明 |
SQLString | 表示要执行的SQL语句 |
OLEDBConnectionString | 为连接到SQL Server服务器的连接字符串 |
sql server 2000与sql server ce2.0通过SqlCeRemoteDataAccess实现数据同步
我已经安装过sql server 2000和sql server ce2.0,接下来只是给这两个安装补丁,我安装的补丁是:Microsoft_sql2ksp4chs1.exe和sqlce20sql2ksp4.exe(也就是sql server ce server tools),确保两个补丁是一样的版本,这里两个都是sp4的。
(1)安装Microsoft_sql2ksp4chs1
要先装这个Microsoft_sql2ksp4chs1,他是sql server2000的很容易安装,按照步骤就好了。
(2)安装sqlce20sql2ksp4.exe
注意:在安装前,确保IIS服务已经启动
i. 按照提示安装
ii. 进入SQL Server CE Virtual Directory Creation Wizard界面
iii. 给virtual directory 输入名称 “sscepubs”(这个你可以自己命名)
iv. 选择“anonymous access”
v. 下一步,不进行任何选择
vi. 安装完成
(3)修改SQL Server 2000
进入SQL Server的企业管理器,在正在运行的Sever中选择安全性,新建登陆,新增加用户IUSER_计算机名(Internet来宾帐号), 并在数据库
访问中选中要访问的数据库,增加角色”db_owner”,点击确定,完成权限设置
(4)测试是否安装成功
在IE中输入http://服务器的IP地址/sscepubs/sscesa20.dll, 如果连接成功且出现“SQL Server CE Agent”
这样子就好了,可以利用SqlCeRemoteDataAccess这个来实现同步了
pull是从 SQL Server 数据库中提取数据并将其存储在 SQL Server CE 数据库的表中
// Connection String to the SQL Server.
string rdaOleDbConnectString = "Provider=sqloledb; Data Source=MySqlServer;Initial Catalog=Northwind; " +
"User Id=username;Password = <password>";
// Initialize RDA Object.
SqlCeRemoteDataAccess rda = null;
try {
//Try the Pull Operation.
rda = new SqlCeRemoteDataAccess();
rda.InternetLogin = "MyLogin";
rda.InternetPassword = "<password>";
rda.InternetUrl = "http://服务器的IP地址/sscepubs/sscesa20.dll";
rda.LocalConnectionString = @"Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0;Data Source=\ssce.sdf";
rda.Pull(
"Employees",
"Select * from Employees",
rdaOleDbConnectString,
RdaTrackOption.TrackingOnWithIndexes ,
"ErrorTable");
}
catch(SqlCeException) {
//Use you own Error Handling Routine.
}
finally {
//Dispose of the RDA Object.
rda.Dispose();
}
push是将 SQL Server CE 数据库中跟踪提取表中的更改传送回 SQL Server 表
string rdaOleDbConnectString = "Provider=sqloledb; Data Source=MySqlServer;Initial Catalog=Northwind; " +
"User Id=username;Password = <password>";
// Initialize RDA Object.
SqlCeRemoteDataAccess rda = null;
try {
//Try the Pull Operation.
rda = new SqlCeRemoteDataAccess();
rda.InternetLogin = "MyLogin";
rda.InternetPassword = "<password>";
rda.InternetUrl = "http://服务器的IP地址/sscepubs/sscesa20.dll";
rda.LocalConnectionString = @"Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0;Data Source=\ssce.sdf";
rda.Push("MyLocalTable",
rdaOleDbConnectString,
RdaBatchOption.BatchingOn);
}
catch(SqlCeException) {
//Use you own Error Handling Routine.
}
finally {
//Dispose of the RDA Object.
rda.Dispose();
}
刚接触pda开发,什么都不懂,一点点地摸索吧,谢谢我的同事!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Net;
using System.IO;
namespace WinAppGrid
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//创建数据库的表
private Boolean CreateTable()
{
try
{
SqlCeConnection myconn = new SqlCeConnection("DataSource=mysdf.sdf");
SqlCeCommand com = new SqlCeCommand("create table PC (PCNO NVarChar(10) primary key,XH NVarChar(10) NOT NULL,WERKS NVarChar(4) NOT NULL,PC_DATE NVarChar(10))");
myconn.Open();
com.Connection = myconn;
com.ExecuteNonQuery();
myconn.Close();
MessageBox.Show("创建数据库成功!");
return true;
}
catch (Exception ex)
{
MessageBox.Show("创建数据库失败" + ex.ToString().Substring(1, 60));
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
//创建数据库
try
{
if ( File.Exists("mysdf.sdf"))
{
MessageBox.Show("数据库已经存在");
}
else
{
SqlCeEngine eng = new SqlCeEngine("DataSource=mysdf.sdf");
eng.CreateDatabase();
eng.Dispose();
MessageBox.Show("创建数据库成功");
}
Boolean rtu;
rtu = CreateTable();
if (rtu = false)
{
MessageBox.Show("数据表已经存在!");
}
else
{
MessageBox.Show("创建数据表成功!");
}
}
catch(Exception ex)
{
MessageBox.Show("创建数据库失败"+ ex.ToString().Substring(1,60));
}
}
}
}
Q1. 怎么判断用 RDA Pulled 的表是否是被跟踪的?什么是 RDA 订阅表?
A1. 系统表 __sysRDASubscriptions 保存了 RDA 订阅的信息。如果表被拉下来时 tracking 选项打开了(就是 RdaTrackOption.TrackingOn 或 RdaTrackOption.TrackingOnWithIndexes),那么这个表就是 RDA 订阅表。系统表将为它增加一条记录。总之,如果被拉下来的表在 __sysRDASubscriptions 表中有相应的记录,那么它就是被跟踪的。同样,如果表在被拉下来时没有打开 tracking 选项,那么这个表将没有任何 RDA 订阅信息。
Q2. 为什么我会得到“SSCE_M_RESTRICTEDDDL – 28605 - Internal error: DDL operations are not allowed on system tables. [,,,Table name,,]” 错误?这个错误表示什么含义?
A2. 当你用 RDA 拉下一个表,同时设置了 Tracking On 选项(或者当一个表是 RDA 订阅的),对该表的 DDL 操作是受到限制的,所以我们通过从中复制数据的主表来维护架构的完整性。因此,当你尝试对 RDA 订阅表执行 DDL 操作时,你将会遇到这个错误。
Q3. 如何避免“SSCE_M_TABLEALREADYEXISTS – 28573 - The LocalTableName parameter is already specified. [,,,Table name,,]”错误?
A3. 当 RDA 的 Pull 命令参数中,本地表名称或错误表名称所对应的表已经存在时,就会抛出这个错误。有两种方法可以避免这个错误:1)删除引起错误的表 2)改变 RDA Pull 参数。
Q4. 如何避免“Duplicate value cannot be inserted into a unique index. [Table name = __sysRDASubscriptions, Constraint name = c_LocalTableName]”错误?
A4. 在正常情况下,这个错误是不应该发生的。不过有个缺陷可以导致这个错误的出现。关于这个缺陷在 KB Article 920272 中有详细的讨论。如果你正在使用 VS2005 SP1,那么你应该不会再遇到这个错误了。如果你确实遇到了这个错误,那么把所有访问数据库的产品程序文件和客户应用程序放到同一个目录下(比较难理解-_-),最好是 \Windows 目录。
Q5. 如何在执行了 RDA Pull 之后改变 IDENTITY 信息?因为 RDA 不支持标识范围管理(Identity Range Management)。
A5. 虽然用 RDA 拉下来的表是受到 DDL 约束的,但是改变默认值和标识信息是没有受到限制的。你可以使用 ALTER TABLE <Table Name> ALTER COLUMN <Column Name> <int | bigint> IDENTITY(<New Seed>, <New Step>) 语句修改标识信息。
原文:RDA Subscriptions
[名词解释]
RDA:RemoteDataAccess,SQL Server CE 的远程数据访问同步方式。详细介绍看《SQL Server 2005 Mobile Edition 3.0 中的复制和远程数据访问功能的技术对比》
DDL:Data definition language,数据定义语言。
用VS.NET 2005开发SQL MOBILE 2005程序,在RDA同步的PULL函数中的第4个参数只要采用TrackingOn和TrackingOnWithIndexes(另两个参数无问题)就一直发生一个错误:
无法将重复值插入唯一索引中。[Table name=_sysRDASubscriptions,Constraint name=c_LocalTableName]
_sysRDASubscriptions是SQl Mobile 2005自动产生的系统表,而且只有PULL函数中的第4个参数采用TrackingOn和TrackingOnWithIndexes才会产生,_sysRDASubscriptions表的其中一个字段“localTableName”是主键,Pull后_sysRDASubscriptions表里自动生成一条相关的记录。我用Query Analyzer删除PULL的表,但是_sysRDASubscriptions表的相关记录却不会自动删除(系统表无法手动修改),导致我再次PULL后就提示上面的错误!!!
(注:在程序第一次启动后PULL N次都无任何问题,关闭程序后再一次启动就一直出现上面的错误,实在令人费解!! ),当表存在时我在PULL之前都有DROP TABLE,而且我在VS.NET 2003开发SQL SERVER 2.0一直没问题啊!
这个问题我在VS2005 BATE2和VS2005正式版都试过了,同样的错误!!!
问题已经很久了,问了很多地方,一直没有解决过!!!!!!!!!!!!!!
-----------
终于知道了,原来是一个微软的BUG!!!晕
http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B920272
SQL:用RDA实现SQL CE与SQL Server 之间的数据同步
一、 概述
PPC程序与桌面PC进行通信的编程方式目前有两种,1、利用Socket编程与桌面程序进行通信;2、利用RDA和Replication(复制)进行数据库编程来完成与桌面SQL Server数据库的存取。利用Socket编程实际上就是通过TCP/IP协议与桌面PC进行通信,它可以很方便的传输一般类型的数据,譬如:字符串、整数以及字节等,但是如果需要传输类型化的数据则需要程序员自己去封装,而且若想由智能设备从桌面数据库引擎中返回指定数据库表的数据,必须编写桌面接口服务程序来查询数据并将结果通过Socket返回给智能设备。那么如何才能在Pocket PC上做到像在桌面PC上一样存取本地数据库甚至是远程桌面PC的数据库呢?通过在智能设备Pocket PC上运行的SQL Server CE 我们便可以轻松存取放置在Pocket PC上的SQL Server CE数据库,还可以通过SQL Server CE中的RDA或者合并复制快速实现从智能设备上存取远程桌面SQL Server2000的数据库。
二、技术要点
SQL Server CE 全名是Microsoft SQL Server 2000 Windows CE Edition,它为移动智能设备和嵌入式设备提供了一种存取轻量级数据库的解决方案。通过使用Microsoft Visual Studio .NET 或者 Microsoft eMbedded Visual Tools等开发工具,我们可以将SQL Server的企业数据管理能力扩展到基于Windows CE的智能平台之上。SQL Server CE可以应用到三种典型的环境中:
1、开发环境,即用于开发基于SQL Server CE程序的桌面PC,该桌面PC必须包括Microsoft Visual Studio .NET或者Microsoft eMbedded Visual Tools 3.0和Pocket PC SDK开发工具;
2、客户端环境,是用于运行基于SQL Server CE程序的Pocket PC设备,当设备没有可用的网络连接时,可以使用Microsoft ActiveSync来与服务器环境桌面PC进行线缆连接;
3、服务器环境,是运行Microsoft Internet Information 服务(IIS) 和Microsoft SQL Server实例的计算机,可以将IIS和SQL Server部署在同一台已算机上,也可以分别配置到多台计算上。RDA和合并复制都需要通过IIS来与SQL Server进行通信。
SQL Server CE 依靠几个组件来与SQL Server进行数据交换:
1、数据库引擎用于管理基于Windows CE设备上的数据存储,并且跟踪数据库记录的添加、更新和删除操作;
2、SQL Server CE Client Agent 是运行在Windows CE设备上的用于连接的组件,包括复制对象、RDA对象和数据库引擎,使用这些对象应用程序可以控制与SQL Server的连接;
3、SQL Server CE Server Agent 处理来自SQL Server CE Client Agent的Http请求。当SQL Server CE Client Agent通过Http协议向SQL Server CE Server Agent发送请求时,SQL Server CE Server Agent会与SQL Server进行连接并将查询的记录集通过Http协议再传回给SQL Server CE Client Agent,所有数据的传送都要依赖IIS来完成。
由上述通信过程我们知道,SQL Server CE 的远程连接和存取需要使用Web传输协议Http 或者Https,SQL Server CE Client Agent必须运行在Windows CE设备上,SQL Server CE Server Agent则运行在桌面PC上,而且该计算机还必须安装有IIS以便使用RDA 或合并复制来和SQL Server通信。SQL Server CE 支持的网络连接有以太网、无线局域网和无线广域网。通过使用Microsoft ActiveSync,Pocket PC设备可以使用串口、红外线或者USB直接与桌面PC上的SQL Server连接,也可以进行SQL Server CE与桌面SQL Server 的连接测试。
Remote Data Access (RDA)对象是Microsoft SQL Server 2000 Windows CE (SQL Server CE)用于可编程存取远程Microsoft SQL Server 2000 或者Microsoft SQL Server version 7.0 数据库的ActiveX控件,我们可以使用RDA存取远程数据库就像是在桌面PC上操作本地数据库一样简单。
三、设计思路
我们将使用Visual Basic .Net创建“任务管理程序 For PPC”项目来展示如何利用RDA来完成PPC与PC间的数据库连接和存取。一名客户经理助理或销售人员必须知道今天都要完成哪些任务,上级领导对自己都有哪些安排等等信息,虽然可以使用Email或者IM程序进行接收和查看,但是如果我们只拿Pocket PC设备能否完成任务的接收呢?答案当然是肯定的。
在Pocket PC上我们创建数据库客户端程序,编写RDA程序需要用到.net压缩框架中System.Data.SqlServerCe命名空间中的SqlCeRemoteDataAccess类。从桌面PC查询并获取记录集到Pocket PC上我们需要使用rda.pull方法,pull有多种重载版本,我们使用最常用的版本,localTableName 是将要接收提取的 SQL Server 记录的 SQL Server CE 本地表的名称。sqlSelectString 为任何有效的 Transact-SQL 语句,包括 SELECT 语句和存储过程,它们指定从远程 SQL Server 数据库中提取哪些表、列和记录以存储在 SQL Server CE 数据库中。 oledbConnectionString 是连接 SQL Server 数据库时使用的 OLE DB 连接字符串。 trackOption 表示 SQL Server CE 是否跟踪对提取表所做的更改,以及提取的表上存在的索引是否转到具有主键约束的设备。我们使用的版本为:
…. rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes) …. |
TrackingOnWithIndexes指示 SQL Server CE跟踪对所提取表的所有更改。在本地表上同时创建 SQL Server 表上存在的索引和主键约束。
编写PPC数据库程序所用到的控件和类与编写桌面数据库程序具有相似性,SqlCeConnection对应SqlConnection,SqlCeDataAdapter对应SqlDataAdapter,SqlCeCommand对应SqlCommand等,SqlCeConnection 对象表示到智能设备上的数据源的一个连接,需要向ConnectionString传递有效的连接字符串,譬如:
LocalConnString = "Data Source=\Program File\Task\RDA.sdf" |
Sdf文件是SQL Server CE 数据库文件。 SQL Server CE 只支持一次一个连接,但是多个命令可以共享同一连接。在SqlCeConnection连接打开的情况下,可以创建SqlCeCommand对象,并设置用于执行或返回记录集的SQL语句的Commandtext属性,SqlCeCommand 调用的 SQL 语句不支持传递参数的命名参数,必须使用问号 (?) 占位符,也可以自定义组成SQL语句的字符串,例如:
…… Dim conn As New SqlCeConnection conn.ConnectionString = LocalConnString Dim selectCMD As SqlCeCommand = New SqlCeCommand selectCMD.CommandText = "update itemlist set finished=1 where id=" + id conn.Open() selectCMD.ExecuteNonQuery() …… |
应用程序可以使用rda.push方法将 SQL Server CE 跟踪提取表中的更改传送回原始 SQL Server 表。localTableName 是指已经从 SQL Server 提取的记录的 SQL Server CE 本地表的名称。oledbConnectionString 为连接 SQL Server 数据库时使用的 OLE DB 连接字符串。batchOption 表示正发送回 SQL Server 表的更改是组成一批共用同一事务,还是分别应用。我们的版本需要将所有行组成一批,归并到一个事务推入SQL Server。
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
四、 环境配置及程序实现
很多网友不能成功运行SQL Server CE 的RDA和合并复制程序很大程度都是因为配置问题。正确安装SQL CE和配置IIS及SQL Server 2000是运行SQL CE数据库程序的关键。安装SQL Server CE时需要注意,安装程序在安装服务器工具时会抱错,这是SQL Server CE本身与SQL Server 2000存在兼容性及安全性问题,解决的办法是先忽略,然后更新桌面SQL Server 2000数据库引擎到SP3或SP4,根据所做的更新版本还需要运行相应的更新程序SQL Server CE 2.0 SP3 For SQL Server 2000 SP3或者SQL Server CE 2.0 SP4 For SQL Server 2000 SP4,这样SQL Server CE的服务器组件就可以顺利地安装到了计算机中,然后运行其附带的Configure Connectivity Support in IIS创建IIS虚拟目录sqlce,其指向的实际本地路径为:C:\Program Files\Microsoft SQL Server CE 2.0\Server\,可以更改该文件夹路径为其它,但该文件夹下必须放置着SQL Server CE Server Agent的相关文件,比如:sscesa20.dll。下一步需要配置存取该虚拟目录的用户、权限及身份验证方式,我们可以选择匿名访问,并接受IIS的默认来宾用户,一般以IUSR开头,在存取权限中需要选中读取和目录浏览两项,见下图。
![]() |
配置就绪后,我们可以检测SQL Server CE Server Agent工作是否正常,启动IE,在地址栏中输入 Http://localhost/sqlce/sscesa20.dll,或者将localhost改为实际的主机名称,浏览器返回“SQL Server CE Server Agent”说明SQL Server CE Server Agent运行正常,IIS配置正确。
![]() ![]() ![]() |
接下来需要配置SQL Server 2000,我们需要在桌面SQL Server 2000中创建名为Task数据库,包含Employee员工表和ItemList任务表,为ItemList表中ID字段创建主键和索引,并且添加在IIS中设置的可以访问sqlce虚拟目录和其下文件的IIS来宾用户,这样该用户就可通过IIS来存取SQL Server 2000的数据库了。
![]() ![]() ![]() ![]() |
Pocket PC和桌面PC网络连接可以使用Microsoft ActiveSync,也可以使用无线WiFi 802.1x。由于我们是与单台桌面PC连接,需要在其上同时安装IIS和SQL Server 2000。实际使用得知SQL Server CE 2.0运行在桌面服务环境的服务器工具与SQL Server 2000在连接上存在一定问题,微软对此问题的解决办法是:首先将SQL Server 2000打上SP3或者SP4,同时根据SQL Server 2000的补丁版本,还需要给SQL Server CE 2.0打上用于SQL Server 2000 SP3或者 SQL Server 2000 SP4的补丁,SQL Server CE的服务器组件才能顺利工作,上述更新和补丁程序在微软网站上都有下载。
配置结束后启动Visual Studio .Net 2003,单击文件 – 新建 – 项目 - Visual Basic 项目 - 智能设备应用程序,创建空项目。整个程序由一个Form窗体MainForm组成,其上包含两个Panel组件和一个Button组件,我们把程序分为两个主界面,一个为登录界面,一个为操作界面,分别对应两个Panel控件,当登录用Panel显示时,操作用Panel则隐藏,当登录成功后两个Panel的显示属性则相反。Button控件提供退出操作。登录用Panel上面包含几个TextBox和Button控件供填写SQL Server CE Server Agent 的Web地址、要连接的远程SQL Server 2000服务器名称、能够存取桌面SQL Server数据库的用户名和密码,以及要登录的员工ID和密码等必要的登录信息。运行在实际设备上的图示如下:
当单击”登录”按钮时,程序首先在智能设备上创建SQL Server CE本地数据库sdf文件,本程序下载的所有表都保存在该数据库中:
…… ' 根据指定的sdf文件路径创建本地的用户数据库文件用于RDA的PULL en = New SqlCeEngine("Data Source=" & LocalDatabaseFile) en.CreateDatabase() …… |
然后创建RDA对象的实例,并填写用于和远程SQL Server CE Server Agent 通信的相关信息。下载允许登录PPC的合法的用户信息数据到本地表:
rda.Pull("UserInfo", "Select * from employee where emp_id='" + EMPId + "' and emp_password='" + Password + "'", RemoteConnString, RdaTrackOption.TrackingOff) |
UserInfo表返回的是就是登录用户的记录信息,请注意RdaTrackOption的值为TrackingOff,因为我们没有在PPC上设置更改用户信息的操作,所以没必要跟踪该表。如果用户名和密码验证通过,UserInfo表的记录数就为1,也就是大于0,否则没有记录,然后我们通过使用SqlCeConnection、SqlCeDataAdapter、SqlCeDataReader以及DataTable返回UserInfo表的所有记录,一旦记录数为0则不允许登录:
If dtLocalUserInfo.Rows.Count > 0 Then '验证通过 CurrentLogonUserID = dtLocalUserInfo.Rows(0).Item("emp_id").ToString CurrentLogonUserName = dtLocalUserInfo.Rows(0).Item("emp_name").ToString Return True Else '验证失败,返回false Return False End If |
登录成功后根据登录用户名只返回其相关的任务记录,并将任务记录保存在名为” itemlist”的表中:
rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes) |
由于RDA不会保持记录锁,push操作会无条件的将所有数据改动都应用到SQL Server中,所以容易引起当前数据库的其他用户的更新数据的丢失。我们需要按照一定的筛选条件过滤我们感兴趣的记录,以便获取唯一且不同于其它用户返回的记录集。TrackingOnWithIndexes说明在PPC上对任务状态的更改将会被跟踪,在后面的同步操作时会根据跟踪的变化将更改更新到远程数据库中。
任务记录成功获得后,我们隐藏登录用Panel而将操作用Panel置于顶层用于对任务记录的添加、状态更新、删除已经同步操作等。
用listview控件来显示任务记录,我们遍历返回的itemlist表,每一条记录创建一个ListViewItem,并添加到listview中以便显示:
While Reader.Read Dim ls As New ListViewItem(Reader.Item("ID").ToString) ls.SubItems.Add(Trim(Reader.Item("TaskName").ToString)) ls.SubItems.Add(Trim(Reader.Item("TaskContent").ToString)) ls.SubItems.Add(Reader.Item("Finished").ToString) lvItemList.Items.Add(ls) End While |
向SQL Server CE表添加、删除和更新操作同桌面数据库操作相似,例如添加操作:
selectCMD.CommandText = "insert into itemlist (ID,TaskName,TaskContent,Finished,EMP_ID) values (" + _ TextBox1.Text + "," + _ "'" + taskname + "'" + "," + _ "'" + taskcontent + "'" + "," + "0" + "," + "'" + CurrentLogonUserID + "'" + ")" selectCMD.CommandTimeout = 30 conn.Open() selectCMD.ExecuteNonQuery() |
对智能设备本地表进行更新后还需要将改动保存到远程SQL Server中去,我们使用如下代码:
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
将更改成批推入远程SQL Server中,注意:只有跟踪的提取表才可以执行Push操作。运行在实际设备上的图示如下:
![]() |
RDA方式同步ce数据库
首次做移动的程序----数据同步,感觉到.net 是如此的方便!!!!
首先,得配置好开发环境 装上.net2003 sqlserver2000 以及ce development tols server tools后,新增一个iis目录并且配置它为ce server agent端
在浏览器中测试http://localhost/sqlce/sscesa20.dll (sqlce为虚拟目录名称) 返回server agent几字,表明配置正确。
下面为程序代码:
注意:为确保ce中表为可tracked的 故应先pull 后执行push submit等操作。
1。pull
string InternetServer = "http://192.168.10.231/sqlce/sscesa20.dll";
string InternetUser ="Administrator";
string InternetPassword = "dszj1207";
string RemoteConnection = "Provider=sqloledb;Data Source=DSZJ;Initial Catalog=ce;User Id=sa;Password=winwdr";
string LocalDatabase = "\\My Documents\\rc.sdf";
string LocalConnection = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0;Data Source=\\My Documents\\rc.sdf";
string LocalTableName = "students";
string RemoteTableName = "students";
SqlCeRemoteDataAccess rda = new SqlCeRemoteDataAccess(InternetServer, InternetUser, InternetPassword, LocalConnection);
rda.Pull(LocalTableName,"select * from students", RemoteConnection, RdaTrackOption.TrackingOnWithIndexes, "rdaErrors");
rda.Dispose();
}
2。push
SqlCeRemoteDataAccess rda = null;
try
{
rda = new SqlCeRemoteDataAccess();
rda.InternetLogin="Administrator";
rda.InternetPassword="dszj1207";
rda.InternetUrl = "http://192.168.10.231/sqlce/sscesa20.dll";
rda.LocalConnectionString = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0;Data Source=\\My Documents\\rc.sdf";
rda.Push("students", rdaOleDbConnectString, RdaBatchOption.BatchingOff);
}
catch(SqlCeException ex)
{
MessageBox.Show(ex.ToString(), "Error");
}
finally
{
rda.Dispose();
}
3.。submit
SqlCeRemoteDataAccess rda = null;
try
{
rda = new SqlCeRemoteDataAccess(InternetServer, InternetUser, InternetPassword, LocalConnection);
rda.SubmitSql("insert into students values('sunjiguang','010547896321','天津')",RemoteConnection);
}
catch(SqlCeException ex)
{
MessageBox.Show(ex.ToString(), "Error");
}
finally
{
rda.Dispose();
}