Wince MFC OLE DB SQLCE数据库访问技术(二):嵌入式目标平台创建本地数据库sdf文件

时间:2021-07-26 11:20:24

前言

上一节已经讲述了嵌入式目标平台上安装sqlCE,本章将介绍如何在目标平台上创建本地数据库sdf文件。

备注:博客中所有关于Wince MFC OLE DB   SQLCE数据库访问技术的文章都是基于SQL Server 2005 Compact Edition即 sqlCE 3.x

 


 

在讲述sqlCE之前,先来了解下,sqlCE优于wince 自带数据库的特点:

类别 对象 最大大小限制

存储

列名

128 个字符

 

表中的列数

1024

 

行大小

8060 字节

 

数据库密码

40 个字符

 

数据库大小

4 GB 1

 

数据库大小增量

增量为 1 页或 16 页(取决于表大小)

 

页大小

4 KB

 

会话数

256

 

BLOB(ntext 和 image)列的大小

2 GB

 

表名

128 个字符

 

表大小

512 MB

查询

SQL 语句中的字符数

无限制

 

游标中的列数

1024

 

ORDER BY、GROUP BY 或 DISTINCT 子句中的列数

10242

 

嵌套子查询的层数

无限制

 

命名的参数

支持

 

查询中操作数的数量

无限制

 

联接中表的数量

无限制

索引

BLOB 列

无法索引

 

索引键中的字节数

5123

 

索引中的列数

16

 

每个表的索引数

249

约束

PRIMARY KEY、UNIQUE、默认约束和 FOREIGN KEY

支持 4

 

每个表的约束数

249

上表中,我们最为关心的数据,应该是支持的列数和数据量,wince自带数据库最多支持4个字段,而且数据量很有限,而且操作非常复杂。

 

SQL Server Compact Edition 支持下列数据类型:

 

数据类型 说明

bigint

整数数据,从 –2^63 (–9,223,372,036,854,775,808) 到 2^63–1 (9,223,372,036,854,775,807)。存储大小为 8 字节。

integer

整数数据,从 –2^31 (-2,147,483,648) 到 2^31–1 (2,147,483,647)。

存储大小为 4 字节。

smallint

整数数据,从 –32,768 到 32,767。存储大小为 2 字节。

tinyint

整数数据,从 0 到 255。存储大小为 1 字节。

bit

整数数据,值为 1 或 0。

存储大小为 1 位。

numeric (p, s)

精度和小数位数固定的数值数据,取值范围从 –10^38+1 到 10^38–1。p 变量指定精度,取值范围从 1 到 38。s 变量指定小数位数,取值范围从 0 到 p。

存储大小为 19 字节。

money

货币数据值,从 (–2^63/10000) (–922,337,203,685,477.5808) 到 2^63–1 (922,337,203,685,477.5807),准确度为货币单位的万分之一。存储大小为 8 字节。

float

浮点数数据,从 –1.79E +308 到 1.79E+308

存储大小为 8 字节。

real

浮点精度数字数据,从 –3.40E+38 到 3.40E+38。

存储大小为 4 字节。

datetime

日期和时间数据,从 1753 年 1 月 1 日到 9999 年 12 月 31 日,准确度为三百分之一秒或 3.33 毫秒。值被圆整到 .000、.003 或 .007 毫秒增量。

存储为两个 4 字节整数。前 4 个字节存储早于或晚于 base date 1900 年 1 月 1 日的天数。基准日期是系统的参照日期。不允许 datetime 的值早于 1753 年 1 月 1 日。后 4 个字节存储一天之中的具体时间,被表示为从午夜算起的毫秒数。秒数的有效范围是 0–59。

 

格式 示例

YYYY/MM/DD HH:MM:SS

1947/08/15 03:33:20

MM/DD/YYYY HH:MM:SS

04/15/1947 03:33:20

DD MMM YYYY HH:MM:SS

15 Jan 1947 03:33:20

DD MMMM YYYY H:MM:SS

15 January 1947 03:33:20

national character(n)

Synonym:nchar(n)

固定长度的 Unicode 数据,最大长度为 4000 个字符。默认长度 = 1。存储大小(以字节计)是输入的字符数的两倍。

national character varying(n)

Synonym:nvarchar(n)

可变长度的 Unicode 数据,长度值范围为从 1 到 4000 个字符。默认长度 = 1。存储大小(以字节计)是输入的字符数的两倍。

ntext¹

可变长度的 Unicode 数据,最大长度为 (2^30–2)/2 (536,870,911) 个字符。存储大小(以字节计)是输入的字符数的两倍。

Wince MFC OLE DB SQLCE数据库访问技术(二):嵌入式目标平台创建本地数据库sdf文件 注意:
字符串函数中不再支持 ntext。

nchar

n 个字符组成的固定长度的 Unicode 字符数据。n 必须是从 1 到 4,000 的值。存储大小是 n 字节的两倍。

binary(n)

固定长度的二进制数据,最大长度为 8000 字节。默认长度 = 1。

存储大小是固定的,是在类型中声明的以字节为单位的长度。

varbinary(n)

可变长度的二进制数据,最大长度为 8000 字节。默认长度 = 1。

存储大小可变。它表示值的长度(以字节为单位)。

image¹

可变长度的二进制数据,最大长度为 2^30–1 (1,073,741,823) 字节。

存储大小是值的以字节为单位的长度。

uniqueidentifier

全局唯一标识符 (GUID)。存储大小为 16 字节。

IDENTITY [(s, i)]

这是数据列的一个属性,而不是一个独特的数据类型。

只有整数数据类型的数据列可用于标识列。一个表只能有一个标识列。可以指定种子和增量,但不能更新列。

s (seed) = 起始值

i (increment) = 增量值

ROWGUIDCOL

这是数据列的一个属性,而不是一个独特的数据类型。它是一个表中使用 uniqueidentifier 数据类型定义的列。一个表只能有一个 ROWGUIDCOL 列。

¹在 SQL Server Compact Edition 中,当字节数超过 256 时,Ntext 和 image 数据将存储于新的数据页中。由于 SQL Server Compact Edition 数据库可以按页而不是字节进行压缩,因此这会影响数据库的压缩程度。

 

由于MFC没有提供直接操作sqlCE数据库的API和封装好的类,为了访问和操作sqlCE,我们需要借助MFC的OLE DB 来访问和操作sqlCE数据库。

 

 


 

 

下面开始介绍wince 下MFC中通过OLE DB创建我们的第一个helloCE.sdf数据库文件。

 

第一步:创建MFC单文档应用程序工程

 

第二步:包含以下几个头文件

ca_merge30.h

ssceerr30.h

ssceoledb30.h

把这几个头文件复制到EVC查找头文件的地方或者直接复制到应用程序工程当前目录下。然后#include就ok。

然后直接在CHelloCEDoc下添加头文件引用:

[cpp] view plaincopyprint?
  1. #include "ssceoledb30.h"   
  2. #include "ca_merge30.h"   
  3. #include "ssceerr30.h"  

为了演示方便,直接在CHelloCEDoc::CHelloCEDoc()构造函数中创建本地数据库文件helloCE.sdf。

 

CHelloCEDoc::CHelloCEDoc()代码如下:

[cpp] view plaincopyprint?
  1. CHelloCEDoc::CHelloCEDoc()  
  2. {  
  3.     // TODO: add one-time construction code here  
  4.     HRESULT hr;  
  5.     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);  
  6.     if(hr < 0)  
  7.     {  
  8.         MessageBox(NULL, "COM Initialization Failure""ERROR", MB_OK);//出错处理  
  9.                 return;  
  10.     }  
  11.     hr = CreateDatabase();//自己添加的函数  
  12. }  

 

 

CoInitializeEx(NULL, COINIT_MULTITHREADED)是为了初始化COM 环境,由于OLE 依赖于COM ,使用OLE之前,先对COM 环境进行初始化,COINIT_MULTITHREADED,允许多线程。

 

CHelloCEDoc::CreateDatabase()代码如下:

 

 

[cpp] view plaincopyprint?
  1. DBPROP  dbprop[1];  //OLEDB属性  
  2. DBPROPSET dbpropset[1]; //OLEDB属性集   
  3. IDBInitialize  *pIDBInitialize = NULL;  //OLEDE接口指针  
  4. VariantInit(&dbprop[0].vValue);//将vValue初始化为VT_EMPTY,实际定义中,VT_EMPTY= 0        
  5. //创建一个连接数据库的COM接口对象,打开数据库接口IID_IDBInitialize  
  6. hr = CoCreateInstance(  CLSID_SQLSERVERCE_3_0,   
  7.             0,   
  8.             CLSCTX_INPROC_SERVER,   
  9.             IID_IDBInitialize,   
  10.                 (void**)&pIDBInitialize);  
  11. if(hr < 0 )  
  12. {  
  13.     goto Exit;  
  14. }  
  15. //初始化接口属性   
  16. dbprop[0].dwPropertyID  = DBPROP_INIT_DATASOURCE;  
  17. dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
  18. dbprop[0].vValue.vt = VT_BSTR;  
  19. dbprop[0].vValue.bstrVal= SysAllocString("helloCE.sdf");//指定数据库名  
  20. if(NULL == dbprop[0].vValue.bstrVal)  
  21. {  
  22.     hr = E_OUTOFMEMORY;  
  23.     goto Exit;  
  24. }  
  25. //初始化属性集   
  26. dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;  
  27. dbpropset[0].rgProperties    = dbprop;  
  28. dbpropset[0].cProperties     = sizeof(dbprop)/sizeof(dbprop[0]);  
  29. //获取数据库初始化属性,得到的数据库初始化的属性接口指针放在pIDBProperties  
  30. hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties);  
  31. if(hr < 0)  
  32. {  
  33.     goto Exit;  
  34. }  
  35. hr = pIDBProperties->SetProperties(1, dbpropset);   
  36. if(hr < 0)  
  37. {  
  38.     goto Exit;  
  39. }  
  40. //根据初始化的属性连接到数据库   
  41. hr = pIDBInitialize->Initialize();  
  42. if(hr < 0)  
  43. {  
  44.     goto Exit;  
  45. }  
  46. Exit:  
  47. // 清空   
  48. VariantClear(&dbprop[0].vValue);  
  49. // 释放接口   
  50. if(pIDBProperties)  
  51. {  
  52.     pIDBProperties->Release();  
  53. }  
  54. if (pIDBInitialize)  
  55. {  
  56.      pIDBInitialize->Release();  
  57. }  

 

当我们通过创建了IID_IDBInitialize接口之后,就需要设置指定连接数据库的参数,这些参数在OLEDB中,叫做属性,OLEDB的属性被分成几组,每一组就是一个属性集。通常我们需要指定数据库实例名,数据库名,连接数据库的用户名以及密码等等属性。属性集中的属性必须连续存放。此实例中,只定义了一个属性DBPROP[1],所以属性必须以数组形式存放。每个属性都必须单独作为数组的元素来设定。例如,我们要设置数据库名,和访问数据库的密码,我们就要设置两个属性集。

 

例如:

如果我们创建两个属性集,一个用于设置需要打开的数据库名称和打开方式一个用于设置打开数据库时所需的密码

 

[cpp] view plaincopyprint?
  1. // 第一个属性集   
  2. DBPROPSET dbpropset[2];  
  3. DBPROP dbprop[1], sscedbprop[1];  
  4. //设置要访问的数据的名称 和访问方式   
  5. dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;  
  6. dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
  7. dbprop[0].vValue.vt  = VT_BSTR;  
  8. dbprop[0].vValue.bstrVal= SysAllocString(lpsSDFName);  
  9. if(NULL == dbprop[0].vValue.bstrVal)  
  10. {  
  11.     hr = E_OUTOFMEMORY;  
  12.     goto Exit;  
  13. }  
  14.   
  15. dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;  
  16. dbpropset[0].rgProperties         = dbprop;  
  17. dbpropset[0].cProperties         = sizeof(dbprop)/sizeof(dbprop[0]);  
  18.    
  19. //第二个属性集设置特定访问接口行集属性   
  20. //设置访问密码   
  21. sscedbprop[0].dwPropertyID = DBPROP_SSCE_DBPASSWORD;  
  22. sscedbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
  23. sscedbprop[0].vValue.vt = VT_BSTR;  
  24. sscedbprop[0].vValue.bstrVal = SysAllocString(lpsPassWord);   
  25. if(NULL == sscedbprop[0].vValue.bstrVal)  
  26. {      
  27.     hr = E_OUTOFMEMORY;  
  28.     goto Exit;  
  29. }  
  30. dbpropset[1].guidPropertySet = DBPROPSET_SSCE_DBINIT;  
  31. dbpropset[1].rgProperties         = sscedbprop;  
  32. dbpropset[1].cProperties         = sizeof(sscedbprop)/sizeof(sscedbprop[0]);  
  33. //······其他代码   
  34. //设置属性   
  35. hr = pIDBProperties->SetProperties(sizeof(dbpropset)/sizeof(dbpropset[0]), dbpropset);   

 

到此为止本地helloCE.sdf数据库文件已经创建成功。

 

 

 

 

 


版权申明:
转载文章请注明原文出处http://blog.csdn.net/feiyinzilgd/archive/2010/04/01/5441657.aspx

并请联系谭海燕本人或者前往谭海燕个人主页留言