Wince MFC OLE DB SQLCE數據庫訪問技術(二):嵌入式目標平台創建本地數據庫sdf文件
前言
上一節已經講述了嵌入式目標平台上安裝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。
|
||||||||||
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) 個字符。存儲大小(以字節計)是輸入的字符數的兩倍。
|
||||||||||
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下添加頭文件引用:
#include "ssceoledb30.h" #include "ca_merge30.h" #include "ssceerr30.h"
為了演示方便,直接在CHelloCEDoc::CHelloCEDoc()構造函數中創建本地數據庫文件helloCE.sdf。
CHelloCEDoc::CHelloCEDoc()代碼如下:
CHelloCEDoc::CHelloCEDoc() { // TODO: add one-time construction code here HRESULT hr; hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(hr < 0) { MessageBox(NULL, "COM Initialization Failure", "ERROR", MB_OK);//出錯處理 return; } hr = CreateDatabase();//自己添加的函數 }
CoInitializeEx(NULL, COINIT_MULTITHREADED)是為了初始化COM 環境,由於OLE 依賴於COM ,使用OLE之前,先對COM 環境進行初始化,COINIT_MULTITHREADED,允許多線程。
CHelloCEDoc::CreateDatabase()代碼如下:
DBPROP dbprop[1]; //OLEDB屬性 DBPROPSET dbpropset[1]; //OLEDB屬性集 IDBInitialize *pIDBInitialize = NULL; //OLEDE接口指針 VariantInit(&dbprop[0].vValue);//將vValue初始化為VT_EMPTY,實際定義中,VT_EMPTY= 0 //創建一個連接數據庫的COM接口對象,打開數據庫接口IID_IDBInitialize hr = CoCreateInstance( CLSID_SQLSERVERCE_3_0, 0, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize); if(hr < 0 ) { goto Exit; } //初始化接口屬性 dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; dbprop[0].vValue.vt = VT_BSTR; dbprop[0].vValue.bstrVal= SysAllocString("helloCE.sdf");//指定數據庫名 if(NULL == dbprop[0].vValue.bstrVal) { hr = E_OUTOFMEMORY; goto Exit; } //初始化屬性集 dbpropset[0].guidPropertySet = DBPROPSET_DBINIT; dbpropset[0].rgProperties = dbprop; dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]); //獲取數據庫初始化屬性,得到的數據庫初始化的屬性接口指針放在pIDBProperties hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties); if(hr < 0) { goto Exit; } hr = pIDBProperties->SetProperties(1, dbpropset); if(hr < 0) { goto Exit; } //根據初始化的屬性連接到數據庫 hr = pIDBInitialize->Initialize(); if(hr < 0) { goto Exit; } Exit: // 清空 VariantClear(&dbprop[0].vValue); // 釋放接口 if(pIDBProperties) { pIDBProperties->Release(); } if (pIDBInitialize) { pIDBInitialize->Release(); }
當我們通過創建了IID_IDBInitialize接口之後,就需要設置指定連接數據庫的參數,這些參數在OLEDB中,叫做屬性,OLEDB的屬性被分成幾組,每一組就是一個屬性集。通常我們需要指定數據庫實例名,數據庫名,連接數據庫的用戶名以及密碼等等屬性。屬性集中的屬性必須連續存放。此實例中,隻定義了一個屬性DBPROP[1],所以屬性必須以數組形式存放。每個屬性都必須單獨作為數組的元素來設定。例如,我們要設置數據庫名,和訪問數據庫的密碼,我們就要設置兩個屬性集。
例如:
如果我們創建兩個屬性集,一個用於設置需要打開的數據庫名稱和打開方式一個用於設置打開數據庫時所需的密碼
// 第一個屬性集 DBPROPSET dbpropset[2]; DBPROP dbprop[1], sscedbprop[1]; //設置要訪問的數據的名稱 和訪問方式 dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; dbprop[0].vValue.vt = VT_BSTR; dbprop[0].vValue.bstrVal= SysAllocString(lpsSDFName); if(NULL == dbprop[0].vValue.bstrVal) { hr = E_OUTOFMEMORY; goto Exit; } dbpropset[0].guidPropertySet = DBPROPSET_DBINIT; dbpropset[0].rgProperties = dbprop; dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]); //第二個屬性集設置特定訪問接口行集屬性 //設置訪問密碼 sscedbprop[0].dwPropertyID = DBPROP_SSCE_DBPASSWORD; sscedbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; sscedbprop[0].vValue.vt = VT_BSTR; sscedbprop[0].vValue.bstrVal = SysAllocString(lpsPassWord); if(NULL == sscedbprop[0].vValue.bstrVal) { hr = E_OUTOFMEMORY; goto Exit; } dbpropset[1].guidPropertySet = DBPROPSET_SSCE_DBINIT; dbpropset[1].rgProperties = sscedbprop; dbpropset[1].cProperties = sizeof(sscedbprop)/sizeof(sscedbprop[0]); //······其他代碼 //設置屬性 hr = pIDBProperties->SetProperties(sizeof(dbpropset)/sizeof(dbpropset[0]), dbpropset);
到此為止本地helloCE.sdf數據庫文件已經創建成功。
版權申明:
轉載文章請注明原文出處https://blog.csdn.net/feiyinzilgd/archive/2010/04/01/5441657.aspx
最後更新:2017-04-02 04:26:01