OLEDB 靜態繫結和資料轉化介面

2021-08-19 11:28:16 字數 4671 閱讀 5253

oledb 提供了靜態繫結和動態繫結兩種方式,相比動態繫結來說,靜態繫結在使用上更加簡單,而在靈活性上不如動態繫結,動態繫結在前面已經介紹過了,本文主要介紹oledb中的靜態,以及常用的資料型別轉化介面。

之前的例子都是根據返回的columninfo結構來知曉資料表中各項的具體資訊,然後進行繫結操作,這個操作由於可以動態的針對不同的資料型別繫結為不同的型別,因此稱之為動態繫結。動態繫結是建立在我們對資料庫中表結構一無所知,而又需要對資料庫進行程式設計,但是一般在實際的專案中開發人員都是知道資料庫的具體結構的,而且一旦資料庫設計好了後續更改的可能性也不太大,因此可以採取靜態繫結的方式來減少程式設計的複雜度。

在進行靜態繫結時,一般針對每個資料庫表結構定義乙個結構體用來描述表的各項資料,然後利用結構體的偏移來繫結到資料庫中。

一般靜態繫結需要將資料庫表的各項資料與結構體中的成員一一對應,這個時候就涉及到資料庫資料型別到c/c++中資料型別的轉化,下表列舉了常見的資料庫型別到c/c++資料型別的轉化關係

資料庫型別

oledb 型別

c/c++型別

binary

dbtype_bytes/dbtype_iunknown

byte[length]/blob

varbinary

dbtype_bytes/dbtype_iunknown

blob

bitdbtype_bool

variant_bool

char

dbtype_str

char[length]

varchar

dbtype_str

char[length]

nvarchar

dbtype_wstr

wchar_t[length]

nchar

dbtype_wstr

wchar_t[length]

text

dbtype_str/dbtype_iunknown

blob

image

dbtype_bytes/dbtype_iunknown

blob

ntext

dbtype_wstr/dbtype_iunknown

blob

tinyint

dbtype_ui1

byte

smallint

dbtype_i2

short

intdbtype_i4

long

bigint

dbtype_i8

large_integer

real

dbtype_r4

float

float

dbtype_r8

double

money

dbtype_cy

large_integer

numeric

dbtype_numeric

typedef struct tagdb_numeric db_numeric;

decimal

dbtype_numeric

typedef struct tagdb_numeric db_numeric;

sysname

dbtype_wstr

wchar_t[length]

datetime

dbtype_dbtimestamp

typedef struct tagdbtimestamp dbtimestamp;

timestamp

dbtype_bytes

byte[length]

uniqueidentifier

dbtype_guid

guid

下面是乙個靜態繫結的例子

//靜態繫結的結構

typedef

struct _tag_dbstruct

dbstruct, *lpdbstruct;

dbbindings[0].bprecision = 0;

dbbindings[0].bscale = 0;

dbbindings[0].cbmaxlen = sizeof(int);

dbbindings[0].dwmemowner = dbmemowner_clientowned;

dbbindings[0].dwpart = dbpart_status | dbpart_length | dbpart_value;

dbbindings[0].iordinal = pdbcolumninfo[0].iordinal;

dbbindings[0].obstatus = offsetof(dbstruct, dbcodestatus);

dbbindings[0].oblength = offsetof(dbstruct, ucodelength);

dbbindings[0].obvalue = offsetof(dbstruct, ncode);

dbbindings[0].wtype = dbtype_i4;

dbbindings[1].bprecision = 0;

dbbindings[1].bscale = 0;

dbbindings[1].cbmaxlen = sizeof(wchar) * name_length;

dbbindings[1].dwmemowner = dbmemowner_clientowned;

dbbindings[1].dwpart = dbpart_status | dbpart_length | dbpart_value;

dbbindings[1].iordinal = pdbcolumninfo[1].iordinal;

dbbindings[1].obstatus = offsetof(dbstruct, dbnamestatus);

dbbindings[1].oblength = offsetof(dbstruct, unamelength);

dbbindings[1].obvalue = offsetof(dbstruct, szname);

dbbindings[1].wtype = dbtype_wstr;

hres = piaccessor->createaccessor(dbaccessor_rowdata, 2, dbbindings, 0, &haccessor, null);

pdbstruct = (dbstruct*)com_alloc(sizeof(dbstruct) * crows);

while (true)

zeromemory(pdbstruct, sizeof(dbstruct) * crows);

for (int i = 0; i < crowsobtained; i++)

}pirowset->releaserows(crowsobtained, prghrows, null, null, null);

}

我們針對之前的行政區表來進行演示,在這個表中我們只查詢其中的兩列資料,與之前的例子相似,針對每列定義3項資料,分別是狀態,長度和真實的資料,在繫結的時候就不需要計算總體需要記憶體的大小,行記憶體大小就是結構體的大小,在繫結的時候我們結構體成員在結構體中的偏移作為返回資料時各項在緩衝中的偏移。而在訪問資料時就需要自己計算偏移,直接使用結構體中的成員即可。

從上面的例子,我總結了靜態繫結和動態繫結之間的差別:

1. 其實從本質上將動態繫結和靜態繫結沒有區別,都是分配一段緩衝作為行集的緩衝,然後在使用的時候進行偏移的計算

2. 靜態繫結是利用我們提前知道資料庫的結構,實現通過結構體來安排各項在緩衝中的偏移所佔記憶體的大小。

3. 動態繫結中所有成員的分配和所佔記憶體大小都是根據columninfo結構事後動態分配的,需要自己計算偏移。

4. 相比於動態繫結來說,靜態繫結不需要獲取資料庫的各項的屬性資訊,不需要自己計算各項的偏移,相對比較簡單,適用於事先知道資料庫的表結構,使用相對固定,一旦資料庫結構改變就需要改變**

5. 動態繫結可以適用於幾乎任何情形,可擴充套件性強,幾乎不需要考慮資料庫表結構變更問題。**靈活,但是需要自己計算偏移,自己分配管理記憶體,相對來說對程式設計師的功力要求更高一些。

資料庫中資料型別繁多,而對應到具體的程式語言上有不同的展示方式,具體的語言中對同一種資料庫型別有不同的資料型別對應,甚至有的可能並沒有什麼型別可以直接對應,這就涉及到乙個從資料庫資料型別到具體程式語言資料型別之間進行轉換的問題,針對這一問題oledb提供了乙個介面——idataconvert

一般情況下任何資料型別都可以轉化為相應格式的字串,而對應的字串又可以反過來轉化為資料庫中相應的資料型別。當然一些特殊轉換也是允許的,比如:整型資料間的轉換,浮點數間的轉換等。這也是使用這個資料轉化介面的主要原則。

使用com標準的方式建立idataconver介面(呼叫createinstance函式傳入clsid_oledb_conversionlibrary建立乙個iid_idataconvert介面)

接著呼叫該介面的dataconvert方法可以進行資料轉化

呼叫介面的canconvert可以知道兩種資料型別之間能否進行轉化。

呼叫getconversionsize可以知道源資料型別轉化為指定型別時需要的緩衝大小。

這個例子相對比較簡單,就簡單的在之前列印資料庫資料中加了一句轉化為字串的操作,然後列印,就不在文中展示了,具體的例子見我放到碼雲中的**片段

例子**:

1. 靜態繫結

2. 資料型別轉化

treeview 和資料來源繫結

前幾天寫了個asp.net程式,用到了treeview作為左邊選單,依據使用者的角色來初始treeview,比較簡單實用,所以現在總結一下,和博友們共享一下。首先需要乙個關聯式資料庫表結構 就這個結構 nodeid modualid nodename nodeurl 1head1 url 2 hea...

c 靜態方法和資料

c 所有方法都必須在類的內部宣告,但如果把方法或者字段宣告為static就可以使用,類名代用方法或者訪問字段。在方法中宣告乙個靜態變數a 和乙個靜態的afun方法。下面是在主函式中呼叫。從上圖可以看出來我們是直接使用類的名字呼叫這些變數和方法。靜態方法不依賴的例項,不能訪問類的任何例項字段或者例項方...

模板和資料繫結表示式

幾乎所有的資料繫結控制項都支援模板 template 在顯示資料時,可以用模板來格式化每個資料項的布局和外觀。通過模板,可以使用資料繫結表示式來顯示資料項的值。使用模板 除treeview外 2.0中的資料繫結控制項都支援模板。repeater datalist formview必須使用模板顯示資料...