Windows Mobile SQL Ce與SQL Server 的RDA

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開發,什麼都不懂,一點點地摸索吧,謝謝我的同事!

  

(一)安裝.NET CFSQL 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();
        }
        //創建數據庫的表
        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 之間的數據同步

      本文介紹如何利用 RDA(RemoteDataAccess遠程數據存取)實現掌上電腦Pocket PC(簡稱PPC)上的SQL Server CE 2.0與桌面SQL Server 2000數據庫間的數據存取。我們將採用Visual Basic .Net 2003進行智能設備端的程序開發。

  一、 概述

  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();
   }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章