日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ADO学习(四)ADO扩展IADORecordBinding

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ADO学习(四)ADO扩展IADORecordBinding 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

當我們使用Visual?C++進行ADO編程時,一項頗為頭疼的工作就是對VARIANT字段類型的處理。通常做法是,先把VARIANT類型轉換為形式上較為類似的C++類型,然后再把轉換后的數據存放在一個類(class)或結構(structure)中。即便如此,對VARIANT數據類型的處理在一定程度上也影響到了程序的性能。

  ADO為我們提供了一個接口,該接口使我們可以把數據直接讀取到本地,從而繞開對于復雜的VARIANT數據類型的處理。同時,ADO還定義了一組預處理宏,用來簡化接口的使用。用好這一工具,將會使我們的編程工作將變得輕松和高效。

IADORecordBinding接口
VC++ADO的擴展聯系或綁定了一個Recordset對象的各個字段到C/C++變量。當被綁定的Recordset的當前行改變時,其中所有被綁定的字段的值也同樣會被拷貝到相應的C/C++變量中。如果需要,被拷貝的數據還會自動進行相應的數據類型轉換。
IADORecordBinding接口的BindToRecordset方法將字段綁定到C/C++變量之上。AddNew方法則是增加一個新的行到被綁定的RecordsetUpdate方法利用C/C++變量的值填充Recordset中新的行或更新已存在的行。
IADORecordBinding接口由Recordset對象實現,你不需要自己編碼進行實現。

綁定條目
VC++ADO的擴展在一個Recordset對象與一個C/C++變量間進行映像(Map)。一個字段與對應的一個變量間的映像被稱作一個綁定條目。預定義的宏為數字、定長或不定長數據提供了綁定條目。所有的綁定條目與相應的C/C++變量都被封裝、聲明在一個從VC++擴展類CADORecordBinding派生的類中。這個CADORecordBinding類在內部由綁定條目宏定義。
ADO內部,將所有宏的參數都映射在一個OLE?DB?DBBINDING結構中,并創建一個OLE?DB訪問子(Accessor)對象來管理所有的行為和字段與變量間的數據轉換。OLE?DB定義的數據由以下三部分組成:存儲數據的緩沖區;一個狀態值表示一個字段是否被成功地被存入緩沖區,或變量值是否被成功地存入字段;數據長度。(參見OLE?DB程序員參考第6章:讀寫數據的更多信息)

所需的頭文件
為了使用VC++ADO的擴展,你得在你的應用中包含這個頭文件:#include?<icrsint.h>

綁定Recordset的字段
要綁定Recordset的字段到C/C++變量,需要這樣做:?
1.創建一個CADORecordsetBinding的派生類。
2.在派生類中定義綁定條目和相應的C/C++變量。注意不要使用逗號、分號切斷宏。每個宏都會自動地定義適當的分隔符。
為每個被映像的字段定義一個綁定條目。并注意根據不同情況選用ADO_FIXED_LENGTH_ENTRY、?ADO_NUMERIC_ENTRYADO_VARIABLE_LENGTH_ENTRY中的某個宏。
3.在你的應用中,創建一個該派生類的實例。從Recordset中獲得IADORecordBinding接口,然后調用BindToRecordset方法將Recordset的所有字段綁定到對應的C/C++變量之上。
請參見示例程序以獲得更多信息。

接口方法
IADORecordBinding接口只有三個方法:BindToRecordset,?AddNew,Update。每個方法所需的唯一的參數就是一個CADORecordBinding派生類的實例指針。因此,AddNewUpdate方法不能使用任何與它們同名的ADO方法中的參數。

語法
BindToRecordset方法將字段綁定到C/C++變量之上。
BindToRecordset(CADORecordBinding?*binding)
AddNew方法則引用了它的同名ADO函數,來增加一個新的記錄行。
AddNew(CADORecordBinding?*binding)
Update方法也引用了它的同名ADO函數,來更新Recordset
Update(CADORecordBinding?*binding)

綁定條目宏
綁定條目宏定義了一個Recordset字段與一個變量間的對應關系。每個條目的綁定宏由開始宏與結束宏組成并配對使用。
定長數據的宏適用于adDateadBoolean等,數字的宏適用于adTinyInt,?adIntegeradDouble等,變長數據的宏適用于adChar,?adVarCharadVarBinary等。所有的數字類型,除了adVarNumeric以外也是定長數據類型。每個宏的族之間都有不同的參數組,因此你可以排除不感興趣的綁定信息。
參見OLE?DB程序員參考附錄A:數據類型的更多信息

開始綁定條目
BEGIN_ADO_BINDING(Class)

定長數據:
ADO_FIXED_LENGTH_ENTRY(Ordinal,?DataType,?Buffer,?Status,?Modify)
ADO_FIXED_LENGTH_ENTRY2(Ordinal,?DataType,?Buffer,?Modify)
數字型數據:
ADO_NUMERIC_ENTRY(Ordinal,?DataType,?Buffer,?Precision,?Scale,?Status,?Modify)
ADO_NUMERIC_ENTRY2(Ordinal,?DataType,?Buffer,?Precision,?Scale,?Modify)
變長數據:?
ADO_VARIABLE_LENGTH_ENTRY(Ordinal,?DataType,?Buffer,?Size,?Status,?Length,?Modify)
ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,?DataType,?Buffer,?Size,?Status,?Modify)
ADO_VARIABLE_LENGTH_ENTRY3(Ordinal,?DataType,?Buffer,?Size,?Length,?Modify)
ADO_VARIABLE_LENGTH_ENTRY4(Ordinal,?DataType,?Buffer,?Size,?Modify)

結束綁定
END_ADO_BINDING()

?

參數:

描述

Class

綁定單元和C/C++變量定義所在的類。

Ordinal

序數類型,從1開始計數的Recordset字段序號,該字段對應于指定的C/C++變量。

DataType

ADO中的數據類型等價的C/C++數據類型。相應的Recordset字段在需要時將轉換為該數據類型。

Buffer

用來存儲Recordset字段的緩沖區名稱。

Size

緩沖區的最大尺寸。

Status

狀態位。指示緩沖區的內容的有效性,以及字段轉換是否成功。其中有兩個比較重要的值。一個是adFldOK,?表明轉換是成功的;另一個是adFldNull,?表明字段值為NULL。更多的狀態值,請參考MSDN

Modify

布爾類型。如果為TRUE,?表明ADO允許更新緩沖區中的數據。如果為FALSE,表明數據是只讀的。

Precision


數值類型的精度。

Scale

數值類型的小數位數。Number?of?decimal?places?in?a?numeric?variable.

Length


一個四字節的變量。用來包含緩沖區中數據的實際長度。


狀態值
變量Status的值指示了一個字段的值是否被成功的拷貝到了對應的變量中。寫數據時,可以給Status賦值為adFldNull來指示該字段將被設置為null
常量?值?描述
adFldOK?0?一個非空的字段值被返回。
adFldBadAccessor?1?綁定無效。
adFldCantConvertValue?2?值因為符號不匹配或超界外的原因導致無法被正確轉換。
adFldNull?3?讀字段值時,指示一個空值被返回。寫字段值時,指示當字段自身無法編碼NULL時該字段將被設置為NULL
adFldTruncated?4?變長數據或數字被截斷。
adFldSignMismatch?5?值是有符號數,而數據類型是無符號數。
adFldDataOverFlow?6?數據值超出界限。
adFldCantCreate?7?不知名的列類型和字段已經被打開。
adFldUnavailable?8?字段值無法確定。比如一個新的未賦值的無缺省值的字段。
adFldPermissionDenied?9?未被允許更新數據。
adFldIntegrityViolation?10?更新字段時值違反了列的完整性要求。
adFldSchemaViolation?11?更新字段時值違反了列的規范要求。
adFldBadStatus?12?更新字段時,無效的狀態參數。
adFldDefault?13?更新字段時,使用缺省值。

使用VC++ADO的擴展的示例
在這個例子中,還使用了COM專有的智能指針功能,它能自動處理IADORecordBinding接口的QueryInterface和引用計數。如果沒有智能指針,你得這樣編碼:
IADORecordBinding?*picRs?=?NULL;
...
TESTHR(pRs->QueryInterface(
__uuidof(IADORecordBinding),?(LPVOID*)&picRs));
...
if?(picRs)?picRs->Release();
使用智能指針,你可以用這樣的語句從IADORecordBinding接口派生IADORecordBindingPtr類型:
_COM_SMARTPTR_TYPEDEF(IADORecordBinding,?__uuidof(IADORecordBinding));
然后這樣實例化指針:
IADORecordBindingPtr?picRs(pRs);
因為VC++的擴展由Recordset對象實現,因此智能指針picRs的構造函數使用了_RecordsetPtr類指針pRs。構造函數利用pRs調用QueryInterface來獲得IADORecordBinding接口。

//?以下即是示例程序
//?tt.cpp?:?定義控制臺應用程序的入口點。

//

#include?"stdafx.h"

#import?"c:\Program?Files\Common?Files\System\ADO\msado15.dll"?no_namespace?rename("EOF",?"EndOfFile")

?

#include?<icrsint.h>

_COM_SMARTPTR_TYPEDEF(IADORecordBinding,?__uuidof(IADORecordBinding));

?

inline?void?TESTHR(HRESULT?_hr)?{?if?FAILED(_hr)?_com_issue_error(_hr);?}

?

class?CCustomRs?:?public?CADORecordBinding

{

BEGIN_ADO_BINDING(CCustomRs)

ADO_VARIABLE_LENGTH_ENTRY2(1,?adVarChar,?m_sz_SID,sizeof(m_sz_SID),?m_ul_SID,?false)

ADO_VARIABLE_LENGTH_ENTRY2(2,?adVarChar,?m_sz_SNAME,sizeof(m_sz_SNAME),?m_ul_SNAME,?false)

ADO_VARIABLE_LENGTH_ENTRY2(3,?adVarChar,?m_sz_TID,sizeof(m_sz_TID),?m_ul_TID,?false)

END_ADO_BINDING()

public:

?

CHAR????m_sz_SID[22];

CHAR????m_sz_SNAME[32];

CHAR????m_sz_TID[32];

?

ULONG???m_ul_SID;

ULONG???m_ul_SNAME;

ULONG???m_ul_TID;

};

?

int?_tmain(int?argc,?_TCHAR*?argv[])

{

::CoInitialize(NULL);

?

//智能指針

_ConnectionPtr?m_pConnection;

?

try?

{

//創建連接對象實例

m_pConnection.CreateInstance(__uuidof(Connection));

m_pConnection->Open("Provider=SQLOLEDB.1;Password=123456;Persist?Security?Info=True;User?ID=sa;Initial?Catalog=CAMPUS;Data?Source=192.168.0.102","","",adModeUnknown);

//數據集指針

_RecordsetPtr?pRst("ADODB.Recordset");

_variant_t?RecordsAffected;

pRst=m_pConnection->Execute((_bstr_t)("select?*?from?student"),?&RecordsAffected,?adCmdText);

?

//數據集綁定

CCustomRs?rs;

IADORecordBindingPtr?picRs(pRst);

?

TESTHR(picRs->BindToRecordset(&rs));

?

while?(!pRst->EndOfFile)

{

//?處理CCustomRs中的數據

printf("Sid=%s?Sname=%s?Tid=%s\n",rs.m_sz_SID,rs.m_sz_SNAME,rs.m_sz_TID);

?

//?移動到下一行,新行的值會被自動填充到對應的CCustomRs的變量中

pRst->MoveNext();

}

}

catch?(_com_error?&e?)

{

printf("Error:\n");

printf("Code?=?%08lx\n",?e.Error());

printf("Meaning?=?%s\n",?e.ErrorMessage());

printf("Source?=?%s\n",?(LPCSTR)?e.Source());

printf("Description?=?%s\n",?(LPCSTR)?e.Description());

}

::CoUninitialize();

?

return?0;

}

?

?

?

?

?

?

?

?

?

?

總結

以上是生活随笔為你收集整理的ADO学习(四)ADO扩展IADORecordBinding的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。