SQL Server CE 与远程 Access 数据库双向同步

Posted

技术标签:

【中文标题】SQL Server CE 与远程 Access 数据库双向同步【英文标题】:SQL Server CE two way sync with remote Access database 【发布时间】:2017-09-02 21:25:58 【问题描述】:

我正在处理一个非常特殊的遗留项目,我需要为 Windows Mobile 6.5 下的 PDA 设备构建一个应用程序。这些设备有一个本地数据库 (SQL Server CE),我们应该与远程数据库同步 (Microsoft Access),只要它们对接并具有网络访问权限。

所以使用 SQL Server CE 的本地数据库可以正常工作,但我无法找到将其正确同步到 Access 数据库的方法。

我读到 Windows Mobile 6.5 不支持 ODBC 和 OLEDB,我发现的大多数资源都已过时或有空链接,我发现的唯一方法是以 XML 格式导出本地数据库相关表希望为Access构建一个VBA组件以正确导入它们。 (并找出向后同步)。

项目更新和新问题

首先,感谢所有提供有用答案的人,感谢 @josef 使用 this thread 上的自动路径为我节省了大量时间。

因此,出于安全原因,远程 SQL Server 是不可行的(客户端对安全性偏执,不会为我提供服务器)。所以我绑定到 PDA 上的 SQL Server CE 和计算机上的 Access。

关于同步:

导出很好:我正在使用多个 dataAdapter 和 WriteXML 方法来生成当设备重新插入时通过 FTP 传输的 XML 文件。然后这些文件会自动导入 Access 数据库。 (见最后的代码)。

我的问题在于导入:我可以通过 XML 阅读器从 Access 生成的文件中获取数据。然后将这些数据插入数据集(事实上,我什至可以在 PDA 屏幕上打印数据),但 我无法找到在 PDA 数据库上执行“UPSERT”的方法。因此,如果它们已经包含具有相同 ID 的数据,我需要一种创造性的方式来更新/插入数据到表中。

我尝试了两种方法,出现 SQL 错误(据我了解,它是 SQL Server CE 不处理存储过程或 T-SQL)。应该更新一些存储点的“可用”标志的简单查询示例:

try

    SqlCeDataAdapter dataAdapter = new SqlCeDataAdapter();
    DataSet xmlDataSet = new DataSet();
    xmlDataSet.ReadXml(localPath +@"\import.xml");

    dataGrid1.DataSource = xmlDataSet.Tables[1];

    _conn.Open();
    int i = 0;
    for (i = 0; i <= xmlDataSet.Tables[1].Rows.Count - 1; i++)
    
        spot = xmlDataSet.Tables[1].Rows[i].ItemArray[0].ToString();
        is_available = Convert.ToBoolean(xmlDataSet.Tables[1].Rows[i].ItemArray[1]);

        SqlCeCommand importSpotCmd = new SqlCeCommand(@"
                    IF EXISTS (SELECT spot FROM spots WHERE spot=@spot) 
                    BEGIN
                        UPDATE spots SET available=@available
                    END
                    ELSE
                    BEGIN
                    INSERT INTO spots(spot, available) 
                        VALUES(@spot, @available)
                    END", _conn);
        importSpotCmd.Parameters.Add("@spot", spot);
        importSpotCmd.Parameters.Add("@available", is_available);

        dataAdapter.InsertCommand = importSpotCmd;
        dataAdapter.InsertCommand.ExecuteNonQuery();
    
    _conn.Close();

catch (SqlCeException sql_ex)

    MessageBox.Show("SQL database error: " + sql_ex.Message);

我也试过这个查询,同样的问题 SQL server ce 显然不处理 ON DUPLICATE KEY(我认为它是 mysql 特定的)。

INSERT INTO spots (spot, available) 
    VALUES(@spot, @available)
ON DUPLICATE KEY UPDATE spots SET available=@available

导出方法的代码已修复,因此可以正常工作,但对于任何想知道的人来说仍然相关:

    private void exportBtn_Click(object sender, EventArgs e)
    

        const string sqlQuery = "SELECT * FROM storage";
        const string sqlQuery2 = "SELECT * FROM spots";
        string autoPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);  //get the current execution directory

        using (SqlCeConnection _conn = new SqlCeConnection(_connString))
        
            try
            
                SqlCeDataAdapter dataAdapter1 = new SqlCeDataAdapter(sqlQuery, _conn);
                SqlCeDataAdapter dataAdapter2 = new SqlCeDataAdapter(sqlQuery2, _conn);
                _conn.Open();
                DataSet ds = new DataSet("SQLExport");
                dataAdapter1.Fill(ds, "stock");
                dataAdapter2.Fill(ds, "spots");

                ds.WriteXml(autoPath + @"\export.xml");
            
            catch (SqlCeException sql_ex)
            
                MessageBox.Show("SQL database error: " + sql_ex.Message);
            

        
    

【问题讨论】:

您能否使用链接表从 MS Access 到 SQL(或者可能将 MS Access 作为链接服务器添加到 SQL Server 实例中?),然后使用 SQL CE RDA 将设备与删除 SQL 同步?查看codeproject.com/Articles/5984/Pocket-PC-with-SQL-CE 了解 RDA 简介 我认为你的 DataSet 方法是一个可行的解决方案——DataSet 也有一个 WriteXml 方法! Windows Mobile 6.5?令我惊讶的是这个问题不是 5 岁。 我知道,对吧?我正在努力获取几乎没有任何复杂的必要信息(由于缺乏 ActiceSync 支持,我什至无法正确调试),但是,客户端规格...... 【参考方案1】:

由于 Access 或多或少是一个独立的数据库解决方案,我强烈建议使用完整的 SQL Server 和 IIS 来设置 SQL CE 数据和 SQL Server 数据之间的合并复制同步。

这在 Paul Yao 和 David Durant 所著的“Programming the .Net Compact Framework”一书中(第 8 章,同步移动数据)中用完整的示例代码和设置进行了描述。

对于工作同步,必须使用时间戳跟踪对服务器和 CE 设备上定义的表和数据的所有更改(通过 GUID、唯一编号完成),并且必须定义冲突处理。

如果服务器上的数据从未通过其他方式更改,您可以只跟踪设备端的更改,然后将它们推送到 Access 数据库。这可以由另一个执行像 here 描述的 Buld Updates 的应用程序来完成。

如果您不想以昂贵的方式使用 SQL Server,可以使用更便宜的解决方案,包括免费的 SQLite(也可用于 CE 和 Compact Framework)以及用于 SQLite 到 MSAccess 的商业同步工具,例如 DBSync。

如果您有经验,您可以创建自己的 SQLite 到 MS ACCESS 同步工具。

【讨论】:

我让 XML 部分(写入、文件传输和导入)通过安全的 FTP 工作,所以我将花几天时间专注于让 SQL Server 同步工作。我的老板告诉我,她不知道客户端是否允许我们安装/使用 SQL Server(这是一个非常安全和封闭的环境),但如果我能提出一个令人信服的观点...... XML 旨在作为备份,但它可以工作,所以我没问题。 我尝试在 Windows Mobile 设备上使用 SQLite,但找不到任何兼容的解决方案(再次弃用......)。 SQL Server CE 运行良好,我的老板(正在设计 Access 数据库)向我保证她可以将 Access 链接到 SQL Server 表。此外,也可以从 Access 端更改数据。所以 SQL Server/IIS 对我来说似乎是最好的解决方案,假设客户端允许我们使用它。

以上是关于SQL Server CE 与远程 Access 数据库双向同步的主要内容,如果未能解决你的问题,请参考以下文章

多个 MS Access 前端连接到单个远程 SQL Server 后端

了解 localDB 与 SQL Server Express 和 SQL Server CE 的关系

通过 Web 服务将 SQL Server CE 与 SQL Server 2005 同步

将 SQL Server CE 数据库与常规 SQL Server 数据库同步

无法让 SQL Server CE 与 Visual Studio 2005 和 Windows CE 5.0 一起使用

SQL 到 SQL CE:如何读取 SQL 或 Access 数据库并将其写为 SQL CE 数据库?