RDA實(shí)現(xiàn)SQL CE與SQL Server間數(shù)據(jù)存取
PPC程序與桌面PC進(jìn)行通信的編程方式目前有兩種,1、利用Socket編程與桌面程序進(jìn)行通信;2、利用RDA和Replication(復(fù)制)進(jìn)行數(shù)據(jù)庫編程來完成與桌面SQL Server數(shù)據(jù)庫的存取。利用Socket編程實(shí)際上就是通過TCP/IP協(xié)議與桌面PC進(jìn)行通信,它可以很方便的傳輸一般類型的數(shù)據(jù),譬如:字符串、整數(shù)以及字節(jié)等,但是如果需要傳輸類型化的數(shù)據(jù)則需要程序員自己去封裝,而且若想由智能設(shè)備從桌面數(shù)據(jù)庫引擎中返回指定數(shù)據(jù)庫表的數(shù)據(jù),必須編寫桌面接口服務(wù)程序來查詢數(shù)據(jù)并將結(jié)果通過Socket返回給智能設(shè)備。那么如何才能在Pocket PC上做到像在桌面PC上一樣存取本地?cái)?shù)據(jù)庫甚至是遠(yuǎn)程桌面PC的數(shù)據(jù)庫呢?通過在智能設(shè)備Pocket PC上運(yùn)行的SQL Server CE 我們便可以輕松存取放置在Pocket PC上的SQL Server CE數(shù)據(jù)庫,還可以通過SQL Server CE中的RDA或者合并復(fù)制快速實(shí)現(xiàn)從智能設(shè)備上存取遠(yuǎn)程桌面SQL Server2000的數(shù)據(jù)庫
什么叫RDA
遠(yuǎn)程數(shù)據(jù)訪問,即Remote Data Access(簡稱為RDA),這項(xiàng)技術(shù)在Windows CE2.11版本時(shí)已經(jīng)存在,在SQL Server 2000 For CE 出現(xiàn)后,它的功能便更加豐富了,通過使用這項(xiàng)技術(shù)。并利用各種網(wǎng)絡(luò)環(huán)境,用戶可以將Pocket PC 連接到遠(yuǎn)程SQL Server 2000 數(shù)據(jù)庫。如果擁護(hù)是第一次進(jìn)行連接,則移動(dòng)設(shè)備會(huì)從SQL Server 2000 上下載需要查詢的數(shù)據(jù);如果不是第一次查詢,移動(dòng)設(shè)備則會(huì)對比本地?cái)?shù)據(jù)庫和遠(yuǎn)程數(shù)據(jù)庫中的內(nèi)容。并更新遠(yuǎn)程數(shù)據(jù)庫中的信息。
RDA技術(shù)的數(shù)據(jù)傳遞。
通過RDA 技術(shù),可以完成以下幾種類型的數(shù)據(jù)傳遞:
從服務(wù)器端下載數(shù)據(jù)。當(dāng)移動(dòng)設(shè)備上的本地?cái)?shù)據(jù)庫無內(nèi)容時(shí),可以通過RDA技術(shù)從遠(yuǎn)程SQL Server 2000服務(wù)器下載初始化數(shù)據(jù)到本地SQL Server CE數(shù)據(jù)庫。例如,應(yīng)用程序利用RDA技術(shù)下載終端擁護(hù)登陸數(shù)據(jù)和產(chǎn)品原始數(shù)據(jù)到本地移動(dòng)數(shù)據(jù)庫中,從而完成系統(tǒng)的初始化。如果沒有這個(gè)最初的初始化步驟,系統(tǒng)將無法登陸。
向服務(wù)器上傳數(shù)據(jù)。移動(dòng)設(shè)備上的應(yīng)用程序在初始化后能夠讓操作員登陸并使用系統(tǒng)。操作員錄入和采集信息(如GPS的信息和條形碼的信息)都將被保存在移動(dòng)數(shù)據(jù)庫中,此時(shí),有可以利用RDA技術(shù)將本地?cái)?shù)據(jù)上傳到SQL Server 2000服務(wù)器端。值得注意的是,我們在設(shè)計(jì)服務(wù)器端數(shù)據(jù)庫時(shí),在參加同步的表中不能存在自增量字段,否則容易造成上傳數(shù)據(jù)失敗,起原因是不同的移動(dòng)設(shè)備回對表中的同一個(gè)字段做自增。
更新服務(wù)器端數(shù)據(jù)。有的時(shí)候,在多個(gè)移動(dòng)設(shè)備上的數(shù)據(jù)庫和服務(wù)器端的數(shù)據(jù)庫中都可能存在同一條記錄,這時(shí)服務(wù)器的記錄將以最后一次同步移動(dòng)設(shè)備中的記錄為準(zhǔn)。
下達(dá)無返回的T—SQL命令操作遠(yuǎn)程服務(wù)器(Submit SQL)。在移動(dòng)設(shè)備上的應(yīng)用程序能夠利用T-SQL命令遠(yuǎn)程操作SQL Server 2000數(shù)據(jù)庫。這項(xiàng)功能非常實(shí)用,我們通常需要在采集數(shù)據(jù)時(shí)記錄當(dāng)前時(shí)間,但是如果存在多個(gè)移動(dòng)設(shè)備時(shí),各個(gè)移動(dòng)設(shè)備的機(jī)器時(shí)間又可能是不統(tǒng)一,對這種情況的解決方案就是在每次數(shù)據(jù)同步時(shí),利用Submit SQL技術(shù)刷新服務(wù)器時(shí)間,下載這個(gè)時(shí)間并同時(shí)設(shè)定為移動(dòng)設(shè)備的時(shí)間。
SQL Server CE 架構(gòu)圖 如圖 所示。
Pull(拉數(shù)據(jù))
拉數(shù)據(jù)就是Windows CE 從SQL Server 服務(wù)器獲取數(shù)據(jù)的過程,這里也可以理解從服務(wù)器中下載數(shù)據(jù)。用戶不必關(guān)心這之間的處理過程,只需要調(diào)用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;
參數(shù)
|
說明
|
LocalTableName
|
將從服務(wù)器獲取數(shù)據(jù)存儲(chǔ)到此表中。如果此表已經(jīng)存在,將會(huì)發(fā)生錯(cuò)誤。
|
SQLSelectString
|
表示從服務(wù)器獲取數(shù)據(jù)的SQL表達(dá)式,它將控制從服務(wù)器取得什么數(shù)據(jù)。同時(shí)也支持那些返回結(jié)果集的存儲(chǔ)過程和視圖。如果是將服務(wù)器中的多個(gè)表的數(shù)據(jù)傳遞到CE中的一個(gè)表,那么應(yīng)將TRACKOPTION的參數(shù)值設(shè)置成為TRACKINGOFF,表示獲取后的數(shù)據(jù)不能再上傳到服務(wù)器。
|
OLEDBConnectionString
|
連接到SQL Server服務(wù)器的連接字符串
|
RDA_TRACKOPTION
|
表示SQL Serve CE是否跟蹤存儲(chǔ)獲取服務(wù)器數(shù)據(jù)的表(LocalTableName)的變化。它取值是一個(gè)枚舉值,具有如表 所示的四個(gè)取值。
|
ErrorTableName
|
表示CE本地錯(cuò)誤表名。在以后調(diào)用Push方法向服務(wù)器提交變化數(shù)據(jù)時(shí)。如果發(fā)生錯(cuò)誤,此錯(cuò)誤表將被創(chuàng)建,并被寫入錯(cuò)誤信息。如果調(diào)用Pull方法時(shí),此錯(cuò)誤表已經(jīng)存在,將會(huì)發(fā)生錯(cuò)誤。
|
表 參數(shù)TrackOption的取值
常量
|
值
|
說明
|
TRACKINGON
|
1
|
對于接收到數(shù)據(jù)的表,SQL Serve CE將跟蹤所有的變化,主鍵約束將根據(jù)SQLSelectString被執(zhí)行而被創(chuàng)建。此值是默認(rèn)值。
|
TRACKINGOFF
|
0
|
對于接收到數(shù)據(jù)的表,SQL Serve CE將不跟蹤所有的變化,主鍵約束在本地表中也是不會(huì)被創(chuàng)建
|
TRACKINGON_INDEXES
|
2
|
對于接收到數(shù)據(jù)的表,SQL Serve CE將跟蹤所有的變化,索引和主鍵如果已經(jīng)在SQL Server表中存在,并且字段被指定在SQLSelectString查詢語句里,那么服務(wù)器表中的索引和主鍵將創(chuàng)建到CE本地表中。
|
TRACKINGOFF_INDEXES
|
3
|
對于接收到數(shù)據(jù)的表,SQL Serve CE將不跟蹤所有的變化,索引和主鍵如果已經(jīng)在SQL Server表中存在,并且字段被指定在SQLSelectString查詢語句里,那么服務(wù)器表中的索引和主鍵將創(chuàng)建到CE本地表中。
|
Push(推數(shù)據(jù))
推數(shù)據(jù)和拉數(shù)據(jù)是完全相反的兩個(gè)方法。推數(shù)據(jù)則是將CE本地庫中的數(shù)據(jù)上傳到服務(wù)器中。Push方法的定義如下:
Virtual /* [id] */ HRESULT STSMETHODCALLTYPY Push(
/* [in] */ BSTR LocalTableName,
/* [in] */BSTR OLEDBConnectionString,
/* [defaultvalue][in] */ RDA_BATCHOPTION BatchOption)=0;
參數(shù)
|
說明
|
LocalTableName
|
表示將向服務(wù)器上傳的變化數(shù)據(jù)的表名
|
OLEDBConnectionString
|
為連接到SQL Server服務(wù)器的連接字符串
|
RDA_BATCHOPTION
|
表示上傳數(shù)據(jù)的方法。它取值是一個(gè)枚舉值,具有如表 所示的兩個(gè)取值。
|
表 參數(shù)BatchOption的取值
常量
|
值
|
說明
|
BATCHINGOFF
|
|
上傳的數(shù)據(jù)被一條一條更新到服務(wù)器
|
BATCHINGON
|
|
上傳的數(shù)據(jù)被一次性的更新到服務(wù)器
|
Submit(遠(yuǎn)程T-SQL操作)
Submit方法可以執(zhí)行遠(yuǎn)程SQL語句,也就是可以將SQL語句傳遞到服務(wù)器上直接執(zhí)行,其定義如下:
Virtual /* [id] */ HRESULT STSMETHODCALLTYPY Submit(
/* [in] */ BSTR SQLString,,
/* [in] */BSTR OLEDBConnectionString,)=0;
屬性
|
說明
|
SQLString
|
表示要執(zhí)行的SQL語句
|
OLEDBConnectionString
|
為連接到SQL Server服務(wù)器的連接字符串
|
sql server 2000與sql server ce2.0通過SqlCeRemoteDataAccess實(shí)現(xiàn)數(shù)據(jù)同步
我已經(jīng)安裝過sql server 2000和sql server ce2.0,接下來只是給這兩個(gè)安裝補(bǔ)丁,我安裝的補(bǔ)丁是:Microsoft_sql2ksp4chs1.exe和sqlce20sql2ksp4.exe(也就是sql server ce server tools),確保兩個(gè)補(bǔ)丁是一樣的版本,這里兩個(gè)都是sp4的。
(1)安裝Microsoft_sql2ksp4chs1
要先裝這個(gè)Microsoft_sql2ksp4chs1,他是sql server2000的很容易安裝,按照步驟就好了。
(2)安裝sqlce20sql2ksp4.exe
注意:在安裝前,確保IIS服務(wù)已經(jīng)啟動(dòng)
i. 按照提示安裝
ii. 進(jìn)入SQL Server CE Virtual Directory Creation Wizard界面
iii. 給virtual directory 輸入名稱 “sscepubs”(這個(gè)你可以自己命名)
iv. 選擇“anonymous access”
v. 下一步,不進(jìn)行任何選擇
vi. 安裝完成
(3)修改SQL Server 2000
進(jìn)入SQL Server的企業(yè)管理器,在正在運(yùn)行的Sever中選擇安全性,新建登陸,新增加用戶IUSER_計(jì)算機(jī)名(Internet來賓帳號), 并在數(shù)據(jù)庫
訪問中選中要訪問的數(shù)據(jù)庫,增加角色”db_owner”,點(diǎn)擊確定,完成權(quán)限設(shè)置
(4)測試是否安裝成功
在IE中輸入http://服務(wù)器的IP地址/sscepubs/sscesa20.dll, 如果連接成功且出現(xiàn)“SQL Server CE Agent”
這樣子就好了,可以利用SqlCeRemoteDataAccess這個(gè)來實(shí)現(xiàn)同步了
pull是從 SQL Server 數(shù)據(jù)庫中提取數(shù)據(jù)并將其存儲(chǔ)在 SQL Server CE 數(shù)據(jù)庫的表中
// 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://服務(wù)器的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 數(shù)據(jù)庫中跟蹤提取表中的更改傳送回 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://服務(wù)器的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開發(fā),什么都不懂,一點(diǎn)點(diǎn)地摸索吧,謝謝我的同事!
(一)安裝.NET CF和SQL CE組件
netcf.core.ppc3.arm.cab
System_SR_chs.cab
sqlce.ppc3.arm.CAB
sqlce.dev.ppc3.arm.CAB
sql.ppc3.arm.CAB
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();
}
//創(chuàng)建數(shù)據(jù)庫的表
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("創(chuàng)建數(shù)據(jù)庫成功!");
return true;
}
catch (Exception ex)
{
MessageBox.Show("創(chuàng)建數(shù)據(jù)庫失敗" + ex.ToString().Substring(1, 60));
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
//創(chuàng)建數(shù)據(jù)庫
try
{
if ( File.Exists("mysdf.sdf"))
{
MessageBox.Show("數(shù)據(jù)庫已經(jīng)存在");
}
else
{
SqlCeEngine eng = new SqlCeEngine("DataSource=mysdf.sdf");
eng.CreateDatabase();
eng.Dispose();
MessageBox.Show("創(chuàng)建數(shù)據(jù)庫成功");
}
Boolean rtu;
rtu = CreateTable();
if (rtu = false)
{
MessageBox.Show("數(shù)據(jù)表已經(jīng)存在!");
}
else
{
MessageBox.Show("創(chuàng)建數(shù)據(jù)表成功!");
}
}
catch(Exception ex)
{
MessageBox.Show("創(chuàng)建數(shù)據(jù)庫失敗"+ ex.ToString().Substring(1,60));
}
}
}
}
Q1. 怎么判斷用 RDA Pulled 的表是否是被跟蹤的?什么是 RDA 訂閱表?
A1. 系統(tǒng)表 __sysRDASubscriptions 保存了 RDA 訂閱的信息。如果表被拉下來時(shí) tracking 選項(xiàng)打開了(就是 RdaTrackOption.TrackingOn 或 RdaTrackOption.TrackingOnWithIndexes),那么這個(gè)表就是 RDA 訂閱表。系統(tǒng)表將為它增加一條記錄。總之,如果被拉下來的表在 __sysRDASubscriptions 表中有相應(yīng)的記錄,那么它就是被跟蹤的。同樣,如果表在被拉下來時(shí)沒有打開 tracking 選項(xiàng),那么這個(gè)表將沒有任何 RDA 訂閱信息。
Q2. 為什么我會(huì)得到“SSCE_M_RESTRICTEDDDL – 28605 - Internal error: DDL operations are not allowed on system tables. [,,,Table name,,]” 錯(cuò)誤?這個(gè)錯(cuò)誤表示什么含義?
A2. 當(dāng)你用 RDA 拉下一個(gè)表,同時(shí)設(shè)置了 Tracking On 選項(xiàng)(或者當(dāng)一個(gè)表是 RDA 訂閱的),對該表的 DDL 操作是受到限制的,所以我們通過從中復(fù)制數(shù)據(jù)的主表來維護(hù)架構(gòu)的完整性。因此,當(dāng)你嘗試對 RDA 訂閱表執(zhí)行 DDL 操作時(shí),你將會(huì)遇到這個(gè)錯(cuò)誤。
Q3. 如何避免“SSCE_M_TABLEALREADYEXISTS – 28573 - The LocalTableName parameter is already specified. [,,,Table name,,]”錯(cuò)誤?
A3. 當(dāng) RDA 的 Pull 命令參數(shù)中,本地表名稱或錯(cuò)誤表名稱所對應(yīng)的表已經(jīng)存在時(shí),就會(huì)拋出這個(gè)錯(cuò)誤。有兩種方法可以避免這個(gè)錯(cuò)誤:1)刪除引起錯(cuò)誤的表 2)改變 RDA Pull 參數(shù)。
Q4. 如何避免“Duplicate value cannot be inserted into a unique index. [Table name = __sysRDASubscriptions, Constraint name = c_LocalTableName]”錯(cuò)誤?
A4. 在正常情況下,這個(gè)錯(cuò)誤是不應(yīng)該發(fā)生的。不過有個(gè)缺陷可以導(dǎo)致這個(gè)錯(cuò)誤的出現(xiàn)。關(guān)于這個(gè)缺陷在 KB Article 920272 中有詳細(xì)的討論。如果你正在使用 VS2005 SP1,那么你應(yīng)該不會(huì)再遇到這個(gè)錯(cuò)誤了。如果你確實(shí)遇到了這個(gè)錯(cuò)誤,那么把所有訪問數(shù)據(jù)庫的產(chǎn)品程序文件和客戶應(yīng)用程序放到同一個(gè)目錄下(比較難理解-_-),最好是 \Windows 目錄。
Q5. 如何在執(zhí)行了 RDA Pull 之后改變 IDENTITY 信息?因?yàn)?RDA 不支持標(biāo)識(shí)范圍管理(Identity Range Management)。
A5. 雖然用 RDA 拉下來的表是受到 DDL 約束的,但是改變默認(rèn)值和標(biāo)識(shí)信息是沒有受到限制的。你可以使用 ALTER TABLE <Table Name> ALTER COLUMN <Column Name> <int | bigint> IDENTITY(<New Seed>, <New Step>) 語句修改標(biāo)識(shí)信息。
原文:RDA Subscriptions
[名詞解釋]
RDA:RemoteDataAccess,SQL Server CE 的遠(yuǎn)程數(shù)據(jù)訪問同步方式。詳細(xì)介紹看《SQL Server 2005 Mobile Edition 3.0 中的復(fù)制和遠(yuǎn)程數(shù)據(jù)訪問功能的技術(shù)對比》
DDL:Data definition language,數(shù)據(jù)定義語言。
用VS.NET 2005開發(fā)SQL MOBILE 2005程序,在RDA同步的PULL函數(shù)中的第4個(gè)參數(shù)只要采用TrackingOn和TrackingOnWithIndexes(另兩個(gè)參數(shù)無問題)就一直發(fā)生一個(gè)錯(cuò)誤:
無法將重復(fù)值插入唯一索引中。[Table name=_sysRDASubscriptions,Constraint name=c_LocalTableName]
_sysRDASubscriptions是SQl Mobile 2005自動(dòng)產(chǎn)生的系統(tǒng)表,而且只有PULL函數(shù)中的第4個(gè)參數(shù)采用TrackingOn和TrackingOnWithIndexes才會(huì)產(chǎn)生,_sysRDASubscriptions表的其中一個(gè)字段“localTableName”是主鍵,Pull后_sysRDASubscriptions表里自動(dòng)生成一條相關(guān)的記錄。我用Query Analyzer刪除PULL的表,但是_sysRDASubscriptions表的相關(guān)記錄卻不會(huì)自動(dòng)刪除(系統(tǒng)表無法手動(dòng)修改),導(dǎo)致我再次PULL后就提示上面的錯(cuò)誤!!!
(注:在程序第一次啟動(dòng)后PULL N次都無任何問題,關(guān)閉程序后再一次啟動(dòng)就一直出現(xiàn)上面的錯(cuò)誤,實(shí)在令人費(fèi)解!! ),當(dāng)表存在時(shí)我在PULL之前都有DROP TABLE,而且我在VS.NET 2003開發(fā)SQL SERVER 2.0一直沒問題啊!
這個(gè)問題我在VS2005 BATE2和VS2005正式版都試過了,同樣的錯(cuò)誤!!!
問題已經(jīng)很久了,問了很多地方,一直沒有解決過!!!!!!!!!!!!!!
-----------
終于知道了,原來是一個(gè)微軟的BUG!!!暈
http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B920272
本文介紹如何利用 RDA(RemoteDataAccess遠(yuǎn)程數(shù)據(jù)存取)實(shí)現(xiàn)掌上電腦Pocket PC(簡稱PPC)上的SQL Server CE 2.0與桌面SQL Server 2000數(shù)據(jù)庫間的數(shù)據(jù)存取。我們將采用Visual Basic .Net 2003進(jìn)行智能設(shè)備端的程序開發(fā)。
一、 概述
PPC程序與桌面PC進(jìn)行通信的編程方式目前有兩種,1、利用Socket編程與桌面程序進(jìn)行通信;2、利用RDA和Replication(復(fù)制)進(jìn)行數(shù)據(jù)庫編程來完成與桌面SQL Server數(shù)據(jù)庫的存取。利用Socket編程實(shí)際上就是通過TCP/IP協(xié)議與桌面PC進(jìn)行通信,它可以很方便的傳輸一般類型的數(shù)據(jù),譬如:字符串、整數(shù)以及字節(jié)等,但是如果需要傳輸類型化的數(shù)據(jù)則需要程序員自己去封裝,而且若想由智能設(shè)備從桌面數(shù)據(jù)庫引擎中返回指定數(shù)據(jù)庫表的數(shù)據(jù),必須編寫桌面接口服務(wù)程序來查詢數(shù)據(jù)并將結(jié)果通過Socket返回給智能設(shè)備。那么如何才能在Pocket PC上做到像在桌面PC上一樣存取本地?cái)?shù)據(jù)庫甚至是遠(yuǎn)程桌面PC的數(shù)據(jù)庫呢?通過在智能設(shè)備Pocket PC上運(yùn)行的SQL Server CE 我們便可以輕松存取放置在Pocket PC上的SQL Server CE數(shù)據(jù)庫,還可以通過SQL Server CE中的RDA或者合并復(fù)制快速實(shí)現(xiàn)從智能設(shè)備上存取遠(yuǎn)程桌面SQL Server2000的數(shù)據(jù)庫。
二、技術(shù)要點(diǎn)
SQL Server CE 全名是Microsoft SQL Server 2000 Windows CE Edition,它為移動(dòng)智能設(shè)備和嵌入式設(shè)備提供了一種存取輕量級數(shù)據(jù)庫的解決方案。通過使用Microsoft Visual Studio .NET 或者 Microsoft eMbedded Visual Tools等開發(fā)工具,我們可以將SQL Server的企業(yè)數(shù)據(jù)管理能力擴(kuò)展到基于Windows CE的智能平臺(tái)之上。SQL Server CE可以應(yīng)用到三種典型的環(huán)境中:
1、開發(fā)環(huán)境,即用于開發(fā)基于SQL Server CE程序的桌面PC,該桌面PC必須包括Microsoft Visual Studio .NET或者M(jìn)icrosoft eMbedded Visual Tools 3.0和Pocket PC SDK開發(fā)工具;
2、客戶端環(huán)境,是用于運(yùn)行基于SQL Server CE程序的Pocket PC設(shè)備,當(dāng)設(shè)備沒有可用的網(wǎng)絡(luò)連接時(shí),可以使用Microsoft ActiveSync來與服務(wù)器環(huán)境桌面PC進(jìn)行線纜連接;
3、服務(wù)器環(huán)境,是運(yùn)行Microsoft Internet Information 服務(wù)(IIS) 和Microsoft SQL Server實(shí)例的計(jì)算機(jī),可以將IIS和SQL Server部署在同一臺(tái)已算機(jī)上,也可以分別配置到多臺(tái)計(jì)算上。RDA和合并復(fù)制都需要通過IIS來與SQL Server進(jìn)行通信。
SQL Server CE 依靠幾個(gè)組件來與SQL Server進(jìn)行數(shù)據(jù)交換:
1、數(shù)據(jù)庫引擎用于管理基于Windows CE設(shè)備上的數(shù)據(jù)存儲(chǔ),并且跟蹤數(shù)據(jù)庫記錄的添加、更新和刪除操作;
2、SQL Server CE Client Agent 是運(yùn)行在Windows CE設(shè)備上的用于連接的組件,包括復(fù)制對象、RDA對象和數(shù)據(jù)庫引擎,使用這些對象應(yīng)用程序可以控制與SQL Server的連接;
3、SQL Server CE Server Agent 處理來自SQL Server CE Client Agent的Http請求。當(dāng)SQL Server CE Client Agent通過Http協(xié)議向SQL Server CE Server Agent發(fā)送請求時(shí),SQL Server CE Server Agent會(huì)與SQL Server進(jìn)行連接并將查詢的記錄集通過Http協(xié)議再傳回給SQL Server CE Client Agent,所有數(shù)據(jù)的傳送都要依賴IIS來完成。
由上述通信過程我們知道,SQL Server CE 的遠(yuǎn)程連接和存取需要使用Web傳輸協(xié)議Http 或者Https,SQL Server CE Client Agent必須運(yùn)行在Windows CE設(shè)備上,SQL Server CE Server Agent則運(yùn)行在桌面PC上,而且該計(jì)算機(jī)還必須安裝有IIS以便使用RDA 或合并復(fù)制來和SQL Server通信。SQL Server CE 支持的網(wǎng)絡(luò)連接有以太網(wǎng)、無線局域網(wǎng)和無線廣域網(wǎng)。通過使用Microsoft ActiveSync,Pocket PC設(shè)備可以使用串口、紅外線或者USB直接與桌面PC上的SQL Server連接,也可以進(jìn)行SQL Server CE與桌面SQL Server 的連接測試。
Remote Data Access (RDA)對象是Microsoft SQL Server 2000 Windows CE (SQL Server CE)用于可編程存取遠(yuǎn)程Microsoft SQL Server 2000 或者M(jìn)icrosoft SQL Server version 7.0 數(shù)據(jù)庫的ActiveX控件,我們可以使用RDA存取遠(yuǎn)程數(shù)據(jù)庫就像是在桌面PC上操作本地?cái)?shù)據(jù)庫一樣簡單。
三、設(shè)計(jì)思路
我們將使用Visual Basic .Net創(chuàng)建“任務(wù)管理程序 For PPC”項(xiàng)目來展示如何利用RDA來完成PPC與PC間的數(shù)據(jù)庫連接和存取。一名客戶經(jīng)理助理或銷售人員必須知道今天都要完成哪些任務(wù),上級領(lǐng)導(dǎo)對自己都有哪些安排等等信息,雖然可以使用Email或者IM程序進(jìn)行接收和查看,但是如果我們只拿Pocket PC設(shè)備能否完成任務(wù)的接收呢?答案當(dāng)然是肯定的。
在Pocket PC上我們創(chuàng)建數(shù)據(jù)庫客戶端程序,編寫RDA程序需要用到.net壓縮框架中System.Data.SqlServerCe命名空間中的SqlCeRemoteDataAccess類。從桌面PC查詢并獲取記錄集到Pocket PC上我們需要使用rda.pull方法,pull有多種重載版本,我們使用最常用的版本,localTableName 是將要接收提取的 SQL Server 記錄的 SQL Server CE 本地表的名稱。sqlSelectString 為任何有效的 Transact-SQL 語句,包括 SELECT 語句和存儲(chǔ)過程,它們指定從遠(yuǎn)程 SQL Server 數(shù)據(jù)庫中提取哪些表、列和記錄以存儲(chǔ)在 SQL Server CE 數(shù)據(jù)庫中。 oledbConnectionString 是連接 SQL Server 數(shù)據(jù)庫時(shí)使用的 OLE DB 連接字符串。 trackOption 表示 SQL Server CE 是否跟蹤對提取表所做的更改,以及提取的表上存在的索引是否轉(zhuǎn)到具有主鍵約束的設(shè)備。我們使用的版本為:
….
rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes)
…. |
TrackingOnWithIndexes指示 SQL Server CE跟蹤對所提取表的所有更改。在本地表上同時(shí)創(chuàng)建 SQL Server 表上存在的索引和主鍵約束。
編寫PPC數(shù)據(jù)庫程序所用到的控件和類與編寫桌面數(shù)據(jù)庫程序具有相似性,SqlCeConnection對應(yīng)SqlConnection,SqlCeDataAdapter對應(yīng)SqlDataAdapter,SqlCeCommand對應(yīng)SqlCommand等,SqlCeConnection 對象表示到智能設(shè)備上的數(shù)據(jù)源的一個(gè)連接,需要向ConnectionString傳遞有效的連接字符串,譬如:
LocalConnString = "Data Source=\Program File\Task\RDA.sdf" |
Sdf文件是SQL Server CE 數(shù)據(jù)庫文件。 SQL Server CE 只支持一次一個(gè)連接,但是多個(gè)命令可以共享同一連接。在SqlCeConnection連接打開的情況下,可以創(chuàng)建SqlCeCommand對象,并設(shè)置用于執(zhí)行或返回記錄集的SQL語句的Commandtext屬性,SqlCeCommand 調(diào)用的 SQL 語句不支持傳遞參數(shù)的命名參數(shù),必須使用問號 (?) 占位符,也可以自定義組成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()
…… |
應(yīng)用程序可以使用rda.push方法將 SQL Server CE 跟蹤提取表中的更改傳送回原始 SQL Server 表。localTableName 是指已經(jīng)從 SQL Server 提取的記錄的 SQL Server CE 本地表的名稱。oledbConnectionString 為連接 SQL Server 數(shù)據(jù)庫時(shí)使用的 OLE DB 連接字符串。batchOption 表示正發(fā)送回 SQL Server 表的更改是組成一批共用同一事務(wù),還是分別應(yīng)用。我們的版本需要將所有行組成一批,歸并到一個(gè)事務(wù)推入SQL Server。
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
四、 環(huán)境配置及程序?qū)崿F(xiàn)
很多網(wǎng)友不能成功運(yùn)行SQL Server CE 的RDA和合并復(fù)制程序很大程度都是因?yàn)榕渲脝栴}。正確安裝SQL CE和配置IIS及SQL Server 2000是運(yùn)行SQL CE數(shù)據(jù)庫程序的關(guān)鍵。安裝SQL Server CE時(shí)需要注意,安裝程序在安裝服務(wù)器工具時(shí)會(huì)抱錯(cuò),這是SQL Server CE本身與SQL Server 2000存在兼容性及安全性問題,解決的辦法是先忽略,然后更新桌面SQL Server 2000數(shù)據(jù)庫引擎到SP3或SP4,根據(jù)所做的更新版本還需要運(yùn)行相應(yīng)的更新程序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的服務(wù)器組件就可以順利地安裝到了計(jì)算機(jī)中,然后運(yùn)行其附帶的Configure Connectivity Support in IIS創(chuàng)建IIS虛擬目錄sqlce,其指向的實(shí)際本地路徑為:C:\Program Files\Microsoft SQL Server CE 2.0\Server\,可以更改該文件夾路徑為其它,但該文件夾下必須放置著SQL Server CE Server Agent的相關(guān)文件,比如:sscesa20.dll。下一步需要配置存取該虛擬目錄的用戶、權(quán)限及身份驗(yàn)證方式,我們可以選擇匿名訪問,并接受IIS的默認(rèn)來賓用戶,一般以IUSR開頭,在存取權(quán)限中需要選中讀取和目錄瀏覽兩項(xiàng),見下圖。
配置就緒后,我們可以檢測SQL Server CE Server Agent工作是否正常,啟動(dòng)IE,在地址欄中輸入 Http://localhost/sqlce/sscesa20.dll,或者將localhost改為實(shí)際的主機(jī)名稱,瀏覽器返回“SQL Server CE Server Agent”說明SQL Server CE Server Agent運(yùn)行正常,IIS配置正確。
接下來需要配置SQL Server 2000,我們需要在桌面SQL Server 2000中創(chuàng)建名為Task數(shù)據(jù)庫,包含Employee員工表和ItemList任務(wù)表,為ItemList表中ID字段創(chuàng)建主鍵和索引,并且添加在IIS中設(shè)置的可以訪問sqlce虛擬目錄和其下文件的IIS來賓用戶,這樣該用戶就可通過IIS來存取SQL Server 2000的數(shù)據(jù)庫了。
Pocket PC和桌面PC網(wǎng)絡(luò)連接可以使用Microsoft ActiveSync,也可以使用無線WiFi 802.1x。由于我們是與單臺(tái)桌面PC連接,需要在其上同時(shí)安裝IIS和SQL Server 2000。實(shí)際使用得知SQL Server CE 2.0運(yùn)行在桌面服務(wù)環(huán)境的服務(wù)器工具與SQL Server 2000在連接上存在一定問題,微軟對此問題的解決辦法是:首先將SQL Server 2000打上SP3或者SP4,同時(shí)根據(jù)SQL Server 2000的補(bǔ)丁版本,還需要給SQL Server CE 2.0打上用于SQL Server 2000 SP3或者 SQL Server 2000 SP4的補(bǔ)丁,SQL Server CE的服務(wù)器組件才能順利工作,上述更新和補(bǔ)丁程序在微軟網(wǎng)站上都有下載。
配置結(jié)束后啟動(dòng)Visual Studio .Net 2003,單擊文件 – 新建 – 項(xiàng)目 - Visual Basic 項(xiàng)目 - 智能設(shè)備應(yīng)用程序,創(chuàng)建空項(xiàng)目。整個(gè)程序由一個(gè)Form窗體MainForm組成,其上包含兩個(gè)Panel組件和一個(gè)Button組件,我們把程序分為兩個(gè)主界面,一個(gè)為登錄界面,一個(gè)為操作界面,分別對應(yīng)兩個(gè)Panel控件,當(dāng)?shù)卿浻肞anel顯示時(shí),操作用Panel則隱藏,當(dāng)?shù)卿洺晒髢蓚€(gè)Panel的顯示屬性則相反。Button控件提供退出操作。登錄用Panel上面包含幾個(gè)TextBox和Button控件供填寫SQL Server CE Server Agent 的Web地址、要連接的遠(yuǎn)程SQL Server 2000服務(wù)器名稱、能夠存取桌面SQL Server數(shù)據(jù)庫的用戶名和密碼,以及要登錄的員工ID和密碼等必要的登錄信息。運(yùn)行在實(shí)際設(shè)備上的圖示如下:
當(dāng)單擊”登錄”按鈕時(shí),程序首先在智能設(shè)備上創(chuàng)建SQL Server CE本地?cái)?shù)據(jù)庫sdf文件,本程序下載的所有表都保存在該數(shù)據(jù)庫中:
……
' 根據(jù)指定的sdf文件路徑創(chuàng)建本地的用戶數(shù)據(jù)庫文件用于RDA的PULL
en = New SqlCeEngine("Data Source=" & LocalDatabaseFile)
en.CreateDatabase()
…… |
然后創(chuàng)建RDA對象的實(shí)例,并填寫用于和遠(yuǎn)程SQL Server CE Server Agent 通信的相關(guān)信息。下載允許登錄PPC的合法的用戶信息數(shù)據(jù)到本地表:
rda.Pull("UserInfo", "Select * from employee where emp_id='" + EMPId + "' and emp_password='" + Password + "'", RemoteConnString, RdaTrackOption.TrackingOff) |
UserInfo表返回的是就是登錄用戶的記錄信息,請注意RdaTrackOption的值為TrackingOff,因?yàn)槲覀儧]有在PPC上設(shè)置更改用戶信息的操作,所以沒必要跟蹤該表。如果用戶名和密碼驗(yàn)證通過,UserInfo表的記錄數(shù)就為1,也就是大于0,否則沒有記錄,然后我們通過使用SqlCeConnection、SqlCeDataAdapter、SqlCeDataReader以及DataTable返回UserInfo表的所有記錄,一旦記錄數(shù)為0則不允許登錄:
If dtLocalUserInfo.Rows.Count > 0 Then '驗(yàn)證通過
CurrentLogonUserID = dtLocalUserInfo.Rows(0).Item("emp_id").ToString
CurrentLogonUserName = dtLocalUserInfo.Rows(0).Item("emp_name").ToString
Return True
Else '驗(yàn)證失敗,返回false
Return False
End If |
登錄成功后根據(jù)登錄用戶名只返回其相關(guān)的任務(wù)記錄,并將任務(wù)記錄保存在名為” itemlist”的表中:
rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes) |
由于RDA不會(huì)保持記錄鎖,push操作會(huì)無條件的將所有數(shù)據(jù)改動(dòng)都應(yīng)用到SQL Server中,所以容易引起當(dāng)前數(shù)據(jù)庫的其他用戶的更新數(shù)據(jù)的丟失。我們需要按照一定的篩選條件過濾我們感興趣的記錄,以便獲取唯一且不同于其它用戶返回的記錄集。TrackingOnWithIndexes說明在PPC上對任務(wù)狀態(tài)的更改將會(huì)被跟蹤,在后面的同步操作時(shí)會(huì)根據(jù)跟蹤的變化將更改更新到遠(yuǎn)程數(shù)據(jù)庫中。
任務(wù)記錄成功獲得后,我們隱藏登錄用Panel而將操作用Panel置于頂層用于對任務(wù)記錄的添加、狀態(tài)更新、刪除已經(jīng)同步操作等。
用listview控件來顯示任務(wù)記錄,我們遍歷返回的itemlist表,每一條記錄創(chuàng)建一個(gè)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表添加、刪除和更新操作同桌面數(shù)據(jù)庫操作相似,例如添加操作:
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() |
對智能設(shè)備本地表進(jìn)行更新后還需要將改動(dòng)保存到遠(yuǎn)程SQL Server中去,我們使用如下代碼:
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
將更改成批推入遠(yuǎn)程SQL Server中,注意:只有跟蹤的提取表才可以執(zhí)行Push操作。運(yùn)行在實(shí)際設(shè)備上的圖示如下:
RDA方式同步ce數(shù)據(jù)庫
首次做移動(dòng)的程序----數(shù)據(jù)同步,感覺到.net 是如此的方便!!!!
首先,得配置好開發(fā)環(huán)境 裝上.net2003 sqlserver2000 以及ce development tols server tools后,新增一個(gè)iis目錄并且配置它為ce server agent端
在瀏覽器中測試http://localhost/sqlce/sscesa20.dll (sqlce為虛擬目錄名稱) 返回server agent幾字,表明配置正確。
下面為程序代碼:
注意:為確保ce中表為可tracked的 故應(yīng)先pull 后執(zhí)行push submit等操作。
1。pull
string InternetServer = "
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 = "
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();
}
---------------------------------------------------------
專注移動(dòng)開發(fā)
Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
posted on 2010-03-24 16:23
TiGERTiAN 閱讀(2371)
評論(0) 編輯 收藏