【发布时间】: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 支持,我什至无法正确调试),但是,客户端规格......
标签: c# xml ms-access sql-server-ce windows-mobile-6.5