黎波

Windows Mobile Development for Line of Business
posts - 185, comments - 1260, trackbacks - 43, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

在我发表了《如何将数据导入到 SQL Server Compact Edition 数据库中(一)》一文后,有一位读者提出这样的疑问:示例程序是否能够在 PPC 上跑,直接从远程 PC 上的 SQL Server 数据库读取数据,导入到 PPC 上的 SQL Server CE 数据库中?

事实上是可以的!!!

.NET Compact Framework 支持智能设备应用程序直接访问远程的 SQL Server 数据库,命名空间还是原来的  System.Data.SqlClient。不过,System.Data.SqlClient 命名空间下的类并不在  System.Data.dll 程序集中,而是封装在一个独立的程序集 System.Data.SqlClient.dll 中。这个程序集和它的安装包可以在“C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Client\v2.0”目录下找到。注意,这个程序集需要独立安装,它并不包含在 .NET Compact Framework 的安装包中。



为了证实这一点,我新建了一个叫 CopyTableMobileDemo 的 Visual C# 2005 智能设备项目,添加对 System.Data.SqlServerCe.dll 和 System.Data.SqlClient.dll 的引用,并从原来的示例程序复制了主要代码过来。



接下来有代码几个地方需要稍微修改一下。

1) SQL Server 数据库连接不能使用 Integrated Security=True,要使用 User Id 和 Password。Data Source 要设置成 SQL Server 服务器的 IP 地址或者计算机名称。设置成 IP 地址还是计算机名称是有区别的。如果你的 Windows Mobile 设备或仿真器是通过 ActiveSync 连接到 PC 的,那么请注意 ActiveSync 的连接设置那里,“这台计算机已连接到”选项如果选择的是单位网络,那么请使用计算机名访问,如果选择了 Internet 则使用 IP 地址访问。



// 创建源 SQL Server 数据库连接对象
string srcConnString = "Data Source=bjb-libo;Initial Catalog=Northwind;User Id=sa;Password=1234;";
SqlConnection srcConnection 
= new SqlConnection(srcConnString);

2) SQL Server CE 数据库连接要换成智能设备的文件路径,如果 Data Source 只设置文件名,那么示例程序将会在设备的根目录下创建 SQL Server CE 数据库文件。

// 创建目标 SQL Server Compact Edition 数据库连接对象
string destConnString = "Data Source=Northwind.sdf";
SqlCeConnection destConnection 
= new SqlCeConnection(destConnString);

3) 由于 .NET Compact Framework 只支持 string[] string.Split(params char[] separator),那么首先 SQL Server CE 数据库创建脚本中每条命令的分隔符 GO 需要替换成分号(';')。

CREATE TABLE Products(
    ProductID 
int NOT NULL CONSTRAINT PK_Products PRIMARY KEY,
    ProductName 
nvarchar(40NOT NULL,
    SupplierID 
int NULL,
    CategoryID 
int NULL,
    QuantityPerUnit 
nvarchar(20NULL,
    UnitPrice 
money NULL,
    UnitsInStock 
smallint NULL,
    UnitsOnOrder 
smallint NULL,
    ReorderLevel 
smallint NULL,
    Discontinued 
bit NOT NULL
);

CREATE TABLE Employees(
    EmployeeID 
int NOT NULL CONSTRAINT PK_Employees PRIMARY KEY,
    LastName 
nvarchar(20NOT NULL,
    FirstName 
nvarchar(10NOT NULL,
    Title 
nvarchar(30NULL,
    TitleOfCourtesy 
nvarchar(25NULL,
    BirthDate 
datetime NULL,
    HireDate 
datetime NULL,
    Address 
nvarchar(60NULL,
    City 
nvarchar(15NULL,
    Region 
nvarchar(15NULL,
    PostalCode 
nvarchar(10NULL,
    Country 
nvarchar(15NULL,
    HomePhone 
nvarchar(24NULL,
    Extension 
nvarchar(4NULL,
    Photo 
image NULL,
    Notes 
ntext NULL,
    ReportsTo 
int NULL,
    PhotoPath 
nvarchar(255NULL
);

4) 创建 SQL Server CE 数据库的方法也需要相应改动。

public static void VerifyDatabaseExists(string connectionString)
{
    
using (SqlCeConnection connection = new SqlCeConnection(connectionString))
    {
        
if (!File.Exists(connection.Database))
        {
            
using (SqlCeEngine engine = new SqlCeEngine(connection.ConnectionString))
            {
                engine.CreateDatabase();

                
string[] commands = Properties.Resources.DbSchema.Split(';');

                SqlCeCommand command 
= new SqlCeCommand();
                command.Connection 
= connection;
                connection.Open();
                
string query;
                
for (int i = 0; i < commands.Length; i++)
                {
                    query 
= commands[i].Trim();
                    
if (!string.IsNullOrEmpty(query))
                    {
                        command.CommandText 
= query;
                        command.ExecuteNonQuery();
                    }
                }
            }
        }
    }
}

其他的地方都不需要修改,让我们看看运行的效果:


 

总结:在 Windows Mobile 上直接将远程 SQL Server 的数据导入到 SQL Server CE 中是可行的,并且利用 CopyTable 方法可以很轻松得实现多个表的数据导入。不过从智能设备直接访问 SQL Server 数据库存在一定的局限性,它比较适合局域网环境,并且需要开放 SQL Server 的端口。另外,我还没有测试过大数据量的导入,我担心会存在内存不足的问题。大家可以测试一下!

示例代码下载:sqlce_data_import2.rar

作者:黎波
博客:http://upto.cnblogs.com/
日期:2007年8月8日

Feedback

#1楼    回复  引用  查看    

2007-08-09 10:19 by 毁于随      
如果存在内存不足的情况,那应该哪种导入方式都会出现内存不足.广域网的方式只要做成类似局域网的不就行了吗?只要保证网络是通的就可以了.
RDA和XX(忘了)主要的功能是同步.而用SqlClient只能实时连接.

#2楼    回复  引用  查看    

2007-08-09 10:43 by 黎波      
@毁于随
内存不足我是在SQLCE2.0上遇到过。当你在一个Open的SqlCeConnection上进行多次SqlCeCommand操作之后,会出现内存不足的异常,估计是SQLCE的bug,sqlmobile后我还没有尝试过。
在移动应用中大部分采用的是局域网连接(LAN/WLAN)或GPRS/CDMA/EDGA无线连接,在无线连接下直接连SQL Server理论上是可行的,主要还是性能问题,我自己没有实践过。我现在改成“比较适合”。
正如你所说,SqlClient是实时连接,它对网络稳定性的要求比较高。

#3楼 [楼主]   回复  引用  查看    

2007-08-09 10:46 by 黎波      
欢迎大家继续讨论:P

#4楼    回复  引用    

2007-08-09 21:39 by SUNDAY [未注册用户]
我用过PDA直接连接到SQL 2000的.不过总觉得不稳定..只要数据量处理大的话就不行,而且SqlClient是实时连接,它对网络稳定性的要求比较高。

#5楼    回复  引用    

2007-08-09 21:40 by SUNDAY [未注册用户]
谢谢黎波给我们初学者提供好的资料..

#6楼    回复  引用    

2007-09-20 15:56 by 黎吻雪 [未注册用户]
为什么我一步一步操作下来运行报错?未处理SqlException

string srcConnString = "Data Source=172.16.134.249;Initial Catalog=warehouse1;User Id=sa;Password=sa1;";

#7楼 [楼主]   回复  引用  查看    

2007-09-22 14:25 by 黎波      
@黎吻雪
你用什么网络呢?如果是ActiveSync的方式,注意网络连接设置要选择Internet方式,因为你用了IP地址连接远程数据库。还有SqlException的Message属性是什么内容?

#8楼    回复  引用  查看    

2007-10-01 01:21 by fox23      
厄,不用SQL的人华丽的飘过..

#9楼    回复  引用    

2007-10-11 15:22 by andystar [未注册用户]
我是初用windows CE的,我遇到的问题和7楼一样,无法找到原因,再一个我还想问问,.NET中虚拟出来的测试环境,怎么样设置网络连接呢?我是用单位网络的。

#10楼 [楼主]   回复  引用  查看    

2007-10-22 23:05 by 黎波      
@andystar
我没有遇到这样的问题,问题无法没法重现。

#11楼    回复  引用    

2007-11-01 18:20 by zf [未注册用户]
我遇到这么一个问题:
就是pda访问不到pc上的sqlserver2000,但在pda上能ping到pc的ip地址。访问我的开发的pc机器就可以,我也不知道是怎么回事了。是不是要把sql2000升级到sp4?但是我升级到sp4了还是不行。iis 是 5.1的。还要别的配置吗?用的是ce 5.0的程序。请帮我解决啊。

#12楼    回复  引用    

2007-11-01 19:42 by zf [未注册用户]
解决了,原来是win的防火墙的问题。关了或者开通1433就ok了

#13楼    回复  引用    

2008-01-10 22:46 by Benny Chen [未注册用户]
我的SQL Server 服务器設成 IP 地址都不行連上SQL Server.

若設成计算机名称, 只有通過 ActiveSync 连接到 PC 的才連的上, 若智能设备離開连接PC, 則連不上. 這是什麼問題呢?

#14楼 [楼主]   回复  引用  查看    

2008-01-15 00:46 by 黎波      
@Benny Chen
一般跟ActiveSync的连接设置有关系,设置为Internet时可以用IP地址连接,设置成单位网络只能用计算机名连接。

#15楼    回复  引用    

2008-01-30 15:56 by xuce [未注册用户]
楼主请问,如果是从ORCALE/DB2/SQL2000/mysql,这种不确定的数据库通过网络导入MOBILE SQL应该怎么办?

#16楼 [楼主]   回复  引用  查看    

2008-01-30 22:51 by 黎波      
@xuce
一般先在服务器生成sdf文件,然后再提供http给手机端下载。

#17楼    回复  引用    

2008-03-20 15:04 by 玉儿 [未注册用户]
NET Compact Framework是用System.Data.SqlServerCe来访问数据库,那么.net 可以在PC机是操作SDF文件吗,请楼主帮帮忙.要是可以的话,给我回个邮件,

#18楼 [楼主]   回复  引用  查看    

2008-03-20 16:02 by 黎波      
@玉儿
可以的!
SQL Server 2005 Compact Edition (v3.1) 和 SQL Server Compact 3.5支持。
详情了解:http://www.microsoft.com/sql/compact

#19楼    回复  引用    

2008-04-08 10:08 by 米 [未注册用户]
黎老师,能不能给我一段关于用RDA方式实现数据同步的代码?我用的VS2005的C#智能设备编程,CE2.0已经配置好了.我的邮箱mzh.0630@163.com
谢谢

#20楼 [楼主]   回复  引用  查看    

2008-04-09 20:16 by 黎波      
@米
看看这篇文章吧:
http://tech.it168.com/n/2007-04-25/200704251350593.shtml

#21楼    回复  引用    

2008-04-16 11:20 by zhusz [未注册用户]
我从wince5.0设备上连接数据库pos,string srcConnString = "Data Source=138.88.8.88;Initial Catalog=pos;User ID=sa;Password=;";
运行到srcConnection.Open();的时候报错SqlException,
message是SQL Server does not exist or access denied,
error number = 17
知道这是什么原因吗?谢谢
在pc上通过ip是可以连接到数据库pos的,但是通过机器名却无法连接

#22楼 [楼主]   回复  引用  查看    

2008-04-17 22:12 by 黎波      
@zhusz
看错误可能是SQL Server的访问权限问题,或者是WinCE设备用IP访问不到SQL Server。

#23楼    回复  引用    

2008-04-18 13:20 by zhusz [未注册用户]
问题解决了:之前srcConnection.Open();不成功是连接同事建的基于sql server 2000,我怀疑是sql2000配置有问题,但是同事不清楚怎么弄,我只好自己安装了sql server,我装的是2005版,按照《开发直接访问SQL Server的智能设备应用程序》介绍的配置,这时候srcConnection.Open();是没有问题了,但是运行到CopyTable()中IDataReader srcReader = srcCommand.ExecuteReader();时又出现了异常SystemException,后来想起忘了安装sql server 2005的sp1、sp2,只要将sp1、sp2安装了,就ok了。
现在不清楚的是sql server2000要怎么配置?

#24楼    回复  引用    

2008-04-26 01:02 by hooper [未注册用户]
黎老师您好,您的这篇文章我看了好几遍了,可是我就是不能实现从嵌入式wince上直接连接SQL server2005的数据库。
我使用的是vs2005.
我也参考了好多文章和代码,奇怪的是,生成的程序放在PC机上是可以运行的,能够读到数据,可是放到我的嵌入式设备上就不能读取数据,我能确定我的嵌入式设备能够连入互联网,一开始报的错误是不能找到sqlclient.dll文件,我就把那几个cab全部安装了,然后就是报错说 can 't find P/Invoke DLL:dbnetlib.dll,我就把这个文件拷贝到我的嵌入式设备中,可是仍然有错误,这次的错误没有提示信息,就是一个异常,异常发生于打开数据库的那个语句sqlconnection.open() .
我已经把能够尝试的招数全部尝试了,就是不能解决。
后来我终于搜到了一个和我类似的问题,地址:http://topic.csdn.net/u/20070907/22/b9233803-552e-449b-8c48-9d9ff55c3e38.html
他说是wince6.0的问题,可是如何解决他说的很含糊。。。
这个问题困扰了我好久,我想不是代码的问题,肯定是引用的问题。
请问如何解决这个问题。
谢谢黎老师

#25楼    回复  引用    

2008-04-26 12:09 by alonepb [未注册用户]
dbnetlib.dll
可能你这个拷得不对

#26楼    回复  引用    

2008-04-26 21:45 by hooper [未注册用户]
@alonepb
我找了相应的版本和相应的处理器的dll,应该对的吧。。。
我现在在想是不是wince6.0不能使用3.0版本的sql server compact...

#27楼 [楼主]   回复  引用  查看    

2008-05-06 12:56 by 黎波      
@hooper
@alonepb
这个问题真的不好说,因为我很多做WinCE平台下的.NET CF开发,我觉得这个问题跟ROM有一定的关系。

#28楼    回复  引用    

2008-05-06 21:20 by hooper [未注册用户]
黎老师您好
我又重试了一下,在PPC WM6.0上和Smartphone WM5.0上都测试过了,问题是同样的,未知的一个错误。
您说的ROM是指操作系统的镜像吗?
我用的是PB6.0自己生成的镜像,使用的设备是eBox4300。
如果是ROM的问题的话,那为什么在我的PPC和Smartphone上都不可以使用呢?这个问题真的是太奇怪了。

#29楼    回复  引用    

2008-05-17 17:06 by ff [未注册用户]
gg

#30楼    回复  引用    

2008-05-17 17:10 by 初学者(PPC) [未注册用户]
黎老师,您好.我在从sql2000上下载数据到sqlce2.0上的时候,出现这样的问题
: typeloadexception.如果是几条数据下载的时候是没有错误的,但数据量如果多一点,就会出现这样的错误.请指教这是什么原因呢?
(我用的不是RDA同步,是直接连接服务器下载.)

#31楼 [楼主]   回复  引用  查看    

2008-05-21 23:09 by 黎波      
@hooper
那可能是你安装的sqlce的包有问题,是不是安装错了,文件名是什么?

#32楼 [楼主]   回复  引用  查看    

2008-05-21 23:10 by 黎波      
@初学者(PPC)
请问你用SqlClient访问远程SQL Server吗?这个错误没有遇到过。

#33楼    回复  引用    

2008-05-25 22:45 by hooper [未注册用户]
@黎波
包是没错的,我的设备使用的是x86构架的CPU,系统是WM6.0
我特地注意了一下,就怕装错了。所以包是没有装错,我怀疑是我SQL Server的问题,因为我开始安装的时候,既安装了SQL EXPRESS 也安装了专业版。

#34楼    回复  引用    

2008-06-03 09:47 by 初学者(PPC) [未注册用户]
@黎波
恩,是的.用的是sqlclient连接的.现在问题解决了,也不知道是什么原因产生的,我用的是Symbol3000系列,会不会是与设备有关系?数据下载的时候用的是:
while(dr.reade())
{
...
insert into sqlceDataBase(....)
...
}
读到300或200多条数据的时候就出错了!!

#35楼    回复  引用    

2008-07-17 10:58 by daimadaquan [未注册用户]
Data Source写服务器名称,就是你准备登录时,显示在登录界面上的,直接拷贝就行了

#36楼    回复  引用    

2008-08-16 11:42 by Yu Ming [未注册用户]
黎老师,你好,
我在试从device(emulator)联到PC的SQL2005,可一直有Exception.
用的是C#(vs2008), WM6,Motorala MC75(Symbol),vista
看了您的文章,检查了以下地方

1)SQL2005接受TCP远端连接,采用固定1433port. 在SQL engine删掉了SQLexpress命名, 重装用default。确实可以从别的机子访问,本机用SQLCMD -e -s 127.0.0.1,1433检查port确实有开

2)ConnectString里加1433,或把计算机名换成IP,用不同的framework试了,2.0,3.0,3.5,不行

3)Disable Windows 防火墙,加Sqlserver的exception, 开放端口1433,

4)试了一个不是mobile, 直接windows form的小程序,可以联到数据库。

5)试了两台机子,一抹一样软件vs2008设置,不行,试了vs2005不行,试了ce, WM5, 不行

6)在没run的时候, preview data, 可以

7)想用Linq,可mobile里没有 system.data.linq

8)vista 更新很多次了,vs2008有装sp1, framwwork3.5有装sp1.

9)加装了SQL compact, 不行

感觉就是从emulator往出连,不行。不知那里设置不对。
实在没办法了,项目赶得紧,整整一周了,能指导一下吗。

具体错误代码和屏幕拷贝在下面的连接
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_23647957.html

万分感谢

#37楼 [楼主]   回复  引用  查看    

2008-08-20 18:44 by 黎波      
@Yu Ming
注意ConnectionString的写法,服务器地址你要尝试用机器名和IP都试一试。

#38楼    回复  引用    

2008-09-08 16:28 by kudydei [未注册用户]
黎老师,您好:
我是用(sql server 2000 sp3a+ iis +sql server ce ),开发工具用的是vs2005,PPC开发.测试ie连接,是能连上iss的,连接成功的.但是ISQLW(查询分析器)一直都不知道怎么部署,说是只要运行sqlcommand就会提示安装,但是,运行报了一个dbnetlib.dll错误,在C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Client\v2.0\wce500下面我随便找了一个x86的dbnetlib.dll放进去,然后在同目录下的sql.dev.CHS.wce5.x86.CAB和sql.wce5.x86.CAB都在设备上安装了一下,但提示安装不成功,我不知道是不是x86不对,这个x86,sh4这些怎么区别,在系统上找半天都没找到,怎么安装呢?
还有几个问题
1.现在ado.net已经封装了db2,oracle的连接吗?什么版本下呢?
2.我部署的程序能在wince moblie下成功安装,但是在wince 5.0上却不行,有什么办法吗?难道只能用evc(c++)?

#39楼    回复  引用    

2008-09-08 17:03 by kudydei [未注册用户]
黎老师,您好:
dbnetlib.dll错误解决了,就是C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Client\v2.0\wce500\armv4i
在这里将cab在设备上安装了一下,就可以在设备上查询数据库了,我也不知道为什么,为什么书上都没说,但是安装ISQLW(查询分析器)还是没想法

#40楼    回复  引用    

2008-09-10 09:15 by kudydei [未注册用户]
问题都解决了,呵呵,原来是我对移动编成一些概念还有点模糊

#41楼    回复  引用    

2008-09-10 09:25 by kudydei [未注册用户]
黎老师:
你知道怎么通过GPRS实现设备和服务器通信的对发吗?我现在没有方向,有没有相关资料呢,

#42楼    回复  引用    

2008-09-13 03:16 by 黄永军 [未注册用户]
黎老师
你好!请黎老师指点迷津。
我使用的环境是WINCE5.0 +VS2008 编程语言是C#。能不能先在PC上由ISQLW查询分析器创建的SDF数据库,然后通过同步工具ActiveSync把它拷到设备上?
应该在设备上安装SQL CE的哪个版本?
很多资料都只介绍对PC的数据库操作,但是我要做的是把设备串口接收到的数据存到数据库里面,请教如何编程对已经对设备上存在的SDF数据库进行连接、添加、查询、更新记录的操作?在WINCE5.0 上进行数据库的操作与在WINCE MOBILE 的操作是否相同?
如果能提供一个最简单的例子就太感谢了。
谢谢!

#43楼    回复  引用    

2008-10-07 17:31 by zhusz [未注册用户]
CopyTable有个问题,也就是如果Northwind.sdf已经存在了数据,如果再调用CopyTable,在resultSet.Insert()的时候就会产生SqlCeException:“无法将重复值插入唯一索引中”,通过try-catch是很容易消除这个SqlCeException,只是如果该条记录已经更新了,CopyTable就无法完成device端的更新,不知道楼主有什么好的建议??谢谢!!

#44楼 [楼主]   回复  引用  查看    

2008-10-07 17:45 by 黎波      
@zhusz
这个方法只适用于数据导入,不适用于数据同步。你可以先try...catch,然后删除原有记录再insert。

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-11-23 13:46 编辑过


相关链接: