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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ODBC学习(一)基本理论

發(fā)布時間:2024/4/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ODBC学习(一)基本理论 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.基本理論:

一個基于ODBC的應用程序對數(shù)據(jù)庫的操作不依賴任何DBMS,不直接與DBMS打交道,所有的數(shù)據(jù)庫操作由對應的DBMSODBC驅動程序完成。MFCODBC類對較復雜的ODBC?API進行了封裝,提供了簡化的調(diào)用接口。MFCODBC類主要包括5個類。

?

2.MFCODBC類主要包括以下5個類:

1.?CDatabase:主要功能是建立與數(shù)據(jù)源的連接

2.?CRecordset:代表從數(shù)據(jù)源選擇的一組記錄(記錄集)

3.?CRecordView:提供了一個表單視圖與某個記錄集直接相連,利用對話框數(shù)據(jù)交替機制(DDX)在記錄集與表單視圖的控件之間傳輸數(shù)據(jù)

4.?CFieldExchange:支持記錄字段數(shù)據(jù)交換(RFX),即記錄集字段數(shù)據(jù)成員與相應的數(shù)據(jù)庫的表的字段之間的數(shù)據(jù)交換。

5.?CDBException:代表ODBC類產(chǎn)生的異常。

?

3.有如下四種類型的記錄集:

1??CRecordset::dynaset

動態(tài)記錄集,支持雙向游標,并保持同所連接的數(shù)據(jù)源同步,對數(shù)據(jù)的更新操作可以通過一個fetch操作獲取。這種方式的好處是動態(tài)、即時的瀏覽到當前的記錄。而?其他用戶也會即時看到你對記錄所做出的修改。該選項適合于創(chuàng)建用戶要發(fā)費很多時間來編輯數(shù)據(jù)的應用程序,并且,如果正在編寫大型數(shù)據(jù)庫應用程序,他也是最?佳選擇

2??CRecordset::snapshot

靜態(tài)快照,一旦形成記錄集,此后數(shù)據(jù)源的所有改變都不能體現(xiàn)在記錄集里,應用程序必須重新進行查詢,才能獲取對數(shù)據(jù)的更新。該類型記錄集也支持雙向游標。Snapshot適用于用戶查詢信息(例如生成報表等)而不適用于數(shù)據(jù)編輯

3??CRecordset::dynamic

同?CRecordset::dynaset記錄集相比,CRecordset::dynamic記錄還能在?fetch?操作里同步其它用戶對數(shù)據(jù)的重新排序。

4??CRecordset::forwardOnly

除了不支持逆向游標外,其它特征同CRecordset::snapshot相同。

?

?

?

?

4.詳解CDatabaseCRecordset等類的具體介紹

CDatabase類的成員函數(shù)如下表:

函數(shù)

說明

CDatabase

構造一個對象

Close

關閉數(shù)據(jù)源連接

Open

通過一個ODBC驅動程序創(chuàng)建到數(shù)據(jù)源的連接

OpenEx

通過一個ODBC驅動程序創(chuàng)建到數(shù)據(jù)源的連接

BeginTrans

開始事務

BindParameters

允許在調(diào)用CDatabase::ExecuteSQL前綁定參數(shù)

Cancel

取消異步操作或第二條線程中的過程

CommitTrans

執(zhí)行事務

ExecuteSQL

執(zhí)行SQL語句,不返回記錄

Rollback

回滾事務,數(shù)據(jù)源返回先前的狀態(tài)

該類的屬性屬性如下表:

屬性

說明

CanTransact

如果數(shù)據(jù)源支持事務,返回非零

CanUpdate

如果CDatabase可以更新,返回非零

GetBookmarkPersistence

獲得書簽對記錄集對象的持久性

GetConnect

返回ODBC連接串

GetCursorCommitBehavior

獲得提交事務對記錄集對象的影響

GetCursorRollbackBehavior

獲得回滾事務對記錄集對象的影響

GetDatabaseName

返回當前使用的數(shù)據(jù)庫名

IsOpen

如果當前CDatabase對象連接到數(shù)據(jù)源,返回非零

SetLoginTimeout

設置數(shù)據(jù)源連接的超時數(shù)(秒為單位)

SetQueryTimeout

設置查詢操作的超時數(shù)(秒為單位)

CRecordset類的成員函數(shù)如下表:

成員

說明

m_hstmt

包含記錄集的ODBC陳述句柄,類型為HSTMT

m_nFields

包含記錄集中字段數(shù)據(jù)成員的數(shù)量,類型為UNIT

m_nParams

包含記錄集中參數(shù)數(shù)據(jù)成員的數(shù)量,類型為UNIT

m_pDatabase

包含一個CDatabase對象指針,通過它訪問數(shù)據(jù)源

m_strFilter

包含CString對象,定義SQLWHERE子句

m_strSort

包含CString對象,定義SQLORDER?BY子句

該類的構造方法如下表:

構造方法

說明

Close

關閉記錄集和與之相關的HSTMT

CRecordset

構造一個CRecordset對象

Open

通過獲得表或執(zhí)行記錄集所代表的查詢來打開記錄集

CRecordset類記錄集屬性如下表:

屬性

說明

CanAppend

如果新記錄可以通過Addnew添加到記錄集,返回非零

CanBookmark

如果記錄集支持書簽,返回非零

CanRestart

如果Requery可以被調(diào)用來再次運行記錄集查詢,返回非零

CanScroll

如果可以在記錄中回滾,返回非零

CanTransact

如果數(shù)據(jù)源支持事務,返回非零

CanUpdate

如果記錄集可以被更新,返回非零

GetODBCFieldCount

返回記錄集中字段的數(shù)量

GetRecordCount

返回記錄集中記錄的數(shù)量

GetSQL

獲得SQL字符串

GetStatus

獲得記錄集的狀態(tài)

GetTableName

獲得記錄集所屬的表名

IsBOF

如果記錄集定位在第一條記錄之前,返回非零

IsDeleted

如果記錄集定位在一條刪除的記錄,返回非零

IsEOF

如果記錄集定位在最后一條記錄之后,返回非零

IsOpen

如果調(diào)用過Open函數(shù),返回非零

CRecordset類更行操作如下表:

更新操作

說明

AddNew

準備增加一條新紀錄,調(diào)用Update之后完成添加

CancelUpdate

取消任何未完成的更新

Delete

從記錄集中刪除當前記錄

Edit

準備對當前記錄進行修改,調(diào)用Update后完成修改

Update

通過將新記錄或編輯的數(shù)據(jù)存入數(shù)據(jù)源來完成AddNewEdit操作

CFieldExchange類處理數(shù)據(jù)交換

CFieldExchange類支持數(shù)據(jù)庫類所使用的記錄集字段交換(RFX程式。如果使用自定義的數(shù)據(jù)類型寫數(shù)據(jù)交換程式,會使用這個類。否則不會直接使用此類。RFX在記錄集對象的字段數(shù)據(jù)成員與數(shù)據(jù)源中當前記錄的相應字段之間交換數(shù)據(jù)。

CRecordView類顯示記錄

CRecordView對象用于在控件中顯示數(shù)據(jù)庫記錄的視圖。這種視圖是一種直接連到一個CRecordView對象的格式視圖,它從一個對話框模板創(chuàng)建資源,并將CRecordView對象的字段顯示在對話框模版的控件里。對象利用DDXRFX機制,使窗體上的空間和記錄集的字段值之間數(shù)據(jù)移動自動化,也就是說,用戶不需要編寫一行代碼就可以完成簡單的數(shù)據(jù)庫記錄查看程序。

CDBException類處理異常

CException類派生,以3個繼承的成員變量反映對數(shù)據(jù)庫操作時的異常:

? m_nRetCode:以ODBC返回代碼(SQL_RETURN)的形式表明造成一場的原因

? m_strError:字符串,描述造成拋出異常的錯誤原因

? m_strStateNativeOrigin:字符串,用以描述以ODBC錯誤代碼表示的異常錯誤

?

?

5.詳細編程:

CDatabase類主要是為了建立應用程序和數(shù)據(jù)源的連接功能。應用程序應該先使用CDatabase類的Open()函數(shù)實現(xiàn)與ODBC數(shù)據(jù)源的連接,然后傳遞CDatabase類的指針到CRecordSet類的構造函數(shù)中,使CRecordSet對象與原來的數(shù)據(jù)源結合起來。完成了數(shù)據(jù)源的連接之后,大量的操作集中在數(shù)據(jù)集之上。完成操作之后,先關閉所有記錄集的連接,然后關閉數(shù)據(jù)源的連接。

CDatabase::virtual?BOOL?Open(

LPCTSTR?lpszDSN,//一個數(shù)據(jù)源名,此數(shù)據(jù)源名是通過ODBC管理器注冊的。如果DSN被設定在lpszConnect里,那么lpszDSN不應在被重新設定,lpszDSN應設為NULL。如果沒有設定lpszConnect,而且又把lpszDSN設定為NULL,那么將出現(xiàn)一個對話框,讓用戶選擇數(shù)據(jù)源。

BOOL?bExclusive?=?FALSE,?//默認為FALSE,表示以共享方式打開數(shù)據(jù)源。當前版本的類庫不支持獨占方式,如果設定為TRUE,將失敗

BOOL?bReadOnly?=?FALSE,?//如果希望連接以只讀方式打開,不想對數(shù)據(jù)源進行更新,那么設定為TRUE,所有依靠此連接打開的記錄集全部繼承此屬性。默認值為FALSE

LPCTSTR?lpszConnect?=?_T(ODBC;),?//連接串。連接串可能包含數(shù)據(jù)源名、數(shù)據(jù)源中用戶的ID、密碼和其他信息。整個連接串必須以”ODBC;”開頭。”ODBC;”表示連接是一個ODBC數(shù)據(jù)源。

BOOL?bUseCursorLib?=?TRUE?//如果希望加載ODBC光標動態(tài)連接庫,設定為TRUE

);

//或者也可以顯示ODBC對話框,請用戶提供連接信息

m_pdatabase.Open(NULL);

?

CRecordSet?類的成員變量m_hstmt?代表了定義該記錄集的SQL?語句句柄,m_nFields成員變量保存了記錄集中字段的個數(shù),m_nParams?成員變量保存了記錄集所使用的參數(shù)個數(shù)。CRecordSet?的記錄集通過CDatabase?實例的指針實現(xiàn)同數(shù)據(jù)源的連接,即CRecordSet?的成員變量m_pDatabase。如果記錄集使用了WHERE?子句,m_strFilter?成員變量將保存記錄集的WHERE?子句的內(nèi)容,如果記錄集使用了?ORDER?BY?子句,m_strSort?成員變量將保存記錄集的ORDER?BY?子句的內(nèi)容。

?

CRecordSet類主要是對數(shù)據(jù)集的操作:

記錄的查詢:主要使用CRecordSet類的Open()方法和Requery()成員函數(shù)。在使用CRecordSet的類對象之前,必須使用CRecordSet的成員函數(shù)Open()來獲得有效的記錄集。一旦使用過Open()函數(shù),再次查詢時使用Requery()函數(shù)就可以了。

記錄的添加:只用AddNew()函數(shù),不過必須保證在數(shù)據(jù)庫是在允許添加的模式打開的。

記錄的刪除:調(diào)用Delete()函數(shù)完成,在使用完Delete()函數(shù)之后不用調(diào)用Update()函數(shù)了。

記錄的修改:調(diào)用Edit()函數(shù)完成,在使用過Edit()函數(shù)之后需要調(diào)用Update()函數(shù)將修改結果存入數(shù)據(jù)庫。

撤銷數(shù)據(jù)庫更新操作:如果在增加、刪除或者編輯記錄之后,想撤銷原來的操作,應該在Update()函數(shù)之前使用Move()函數(shù)。CRecordSet::Move(AFX_MOVE_REFRESH);?該函數(shù)用于撤消增加或修改模式,并恢復在增加或修改模式之前的當前記錄。其中參數(shù)AFX_MOVE_REFRESH的值為零。

?

?

直接執(zhí)行SQL操作:雖然通過?CRecordSet?類我們可以完成大多數(shù)的數(shù)據(jù)庫查詢操作,而且在CRecordSet?類的?Open()成員函數(shù)中也可以提供SQL?語句,但有的時候我們還想進行一些其他操作,例如建立新表、刪除表、建立新的字段等等,這時就需要用到CDatabase?類的直接執(zhí)行SQL?語句的機制。通過調(diào)用CDatabase?類的?ExecuteSQL()成員函數(shù)就能夠完成SQL?語句的直接執(zhí)行,代碼如下:

BOOL?CMyDB::ExecuteSQLWithReport?(const?CString&?strSQL)

{

TRY

{

m_pMyDB->ExecuteSQL(strSQL);???//直接執(zhí)行?SQL?語句

}

CATCH(CDBException,e)

{

CString?strMsg;

strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);

strMsg+=strSQL;

return?FALSE;

}

END_CATCH

return?TRUE;

}

需要注意的是,由于不同DBMS?提供的數(shù)據(jù)操作語句不盡相同,直接執(zhí)行SQL?語句可能會破壞軟件的DBMS?無關性,因此在應用中應當慎用此類操作。

?

使用事務:

一般情況下并不需要直接使用CDatabase類型的對象,因為CRecordset類型的對象可以實現(xiàn)大多數(shù)的功能、但是在進行事務處理時,CDatabase就起到關鍵作用。CDatabase?類提供了對數(shù)據(jù)庫進行操作的函數(shù),為了執(zhí)行事務操作,通過調(diào)用CanTransact函數(shù)返回當前的?CDatabase?實例是否支持事務操作,CDatabase?類提供了?BeginTrans函數(shù),當全部數(shù)據(jù)都處理完成后,可以通過調(diào)用CommitTrans函數(shù)提交事務,或者在特殊情況下通過調(diào)用Rollback函數(shù)將處理回退。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

小問題總結:

1.?IsBOFIsEOF

BOOL?IsBOF(?)?const;

返回值:

如果記錄集沒有記錄,或者你已經(jīng)向前游動到第一個記錄之前,則返回非零;否則返回0.

BOOL?IsEOF(?)?const;

返回值

如果記錄集沒有記錄,或者你已經(jīng)滾動到最后一條紀錄之后,則返回非零。否則,返回0.

?

2.Requery()

在使用snapshot模式的時候增加一條記錄,當前程序不會立即刷新記錄集,調(diào)用此函數(shù)會刷新記錄集。調(diào)用此函數(shù)之后,光標在第一個記錄集上面。Requery()有兩個重要用途:一是使記錄集能反映用戶對數(shù)據(jù)源的改變;二是按照新的過濾或排序方法查詢記錄并重新建立記錄集。

?

3.撤消操作?

如果用戶選擇了增加或者修改記錄后希望放棄當前操作,可以在調(diào)用Update()?函數(shù)之前調(diào)用:?CRecordSet::Move(AFX_MOVE_REFRESH);?

來撤消增加或修改模式,并恢復在增加或修改模式之前的當前記錄。其中的參數(shù)AFX_MOVE_REFRESH?的值為零。

?

3.單文檔向導解釋

1.None(不要任何數(shù)據(jù)支持,今后再添加很麻煩)

2.Header?files?only(該工程需要數(shù)據(jù)庫支持,但不清楚細節(jié)時選擇。工程會添加所要求的頭文件和鏈接庫,但必須自己在創(chuàng)建數(shù)據(jù)庫類)

3.Database?view?without?file?support(表示包含數(shù)據(jù)庫頭文件和鏈接庫,并創(chuàng)建記錄集和記錄視圖,應用程序雖有文檔支持,但不支持串行化)

4.Database?view?with?file?support(表示包含數(shù)據(jù)庫頭文件、記錄集和視圖外,程序還支持串行化)

?

4.使用對話框編程時候

CRecordset m_Recordset(&m_Database);

BOOL?rsOpen=m_Recordset.Open(CRecordset::snapshot,"select?*?from?LinkInfo?where?Name='test001'");

?

這個時候你需要從CRecordSet類派生一個自己的新類,綁定數(shù)據(jù)成員就好了

?

5.自動化配置ODBC數(shù)據(jù)源

SQLConfigDataSource();

?

?

?

問題集:

1.?SetFieldNull(NULL);函數(shù)是干嘛用的?

void?SetFieldNull(?void*?pv,?BOOL?bNull?=?TRUE?);

參數(shù):?

pv

指向記錄集中一字段數(shù)據(jù)成員的地址,或為NULL。如果該參數(shù)為NULL,則標記記錄集中所有字段數(shù)據(jù)成員。(C++?NULL與數(shù)據(jù)庫術語中的Null不相同,后者表示“沒有值”)。

bNull

如果要將此字段數(shù)據(jù)成員標記為沒有值(Null),則設置該參數(shù)為一個非零值。如果要將此字段數(shù)據(jù)成員標記為非Null,則設置該參數(shù)為零。


說明:
此成員函數(shù)用來將記錄集的一個字段數(shù)據(jù)成員標記為Null(專指沒有值)或非空。當應用程序將一個新記錄增加到一個記錄集中時,其所有字段數(shù)據(jù)成員初始都設置為Null值,并標記為“臟的”(被修改了)。當應用程序從一個數(shù)據(jù)源中檢取一個記錄時,該記錄的列或是已有值,或是Null。
注意:
此成員函數(shù)對使用成組行檢取的記錄集是不適用的。如果你已經(jīng)實現(xiàn)了成組行檢取,則SetFieldDirty將導致一個失敗斷言。
如果你特別希望將當前記錄的某個字段設計為沒有值,可將bNull設置為TRUE來調(diào)用SetFieldNull函數(shù),以將該字段標記為Null。如果一個字段先前標記為Null,而現(xiàn)在應用程序想要給它一個值,則只需要簡單地設置該字段的新值。
應用程序不需要用SetFieldNull來刪掉Null標志。要確定該字段是否可以為Null,可以調(diào)用IsFieldNullable函數(shù)。
重點:
只能在調(diào)用Edit或AddNew之后才能調(diào)用SetFieldNull函數(shù)。使用NULL作為SetFieldNull函數(shù)的第一個參數(shù),將使該函數(shù)只應用于outputColumns,而不作用于params。例如,調(diào)用
SetFieldNull(?NULL?);
將只設置outputColumns為NULL,而params將不受影響。
要想作用于params,應用程序必須對所想要作用的各個param提供實際地址,例如:
SetFieldNull(?&m_strParam?);
這意味著應用程序不能像對outputColumns一樣將所有params都設置為NULL。
注意:
當設置參數(shù)為Null時,在記錄集打開之前調(diào)用SetFieldNull將導致一個斷言。在這種情況下,可以調(diào)用SetParamNull。
SetFieldNull通過DoFieldExchange實現(xiàn)。

2.?CDatabase::openCDatabase::openEx的區(qū)別?

3.什么是串行化?

它是指將對象存儲到介質(zhì)(如文件、內(nèi)存緩沖區(qū)等)中或是以二進制方式通過網(wǎng)絡傳輸。之后可以通過反串行化從這些連續(xù)的字節(jié)(byte)數(shù)據(jù)重新構建一個與原始對象狀態(tài)相同的對象,因此在特定情況下也可以說是得到一個副本,但并不是所有情況都這樣。

4.執(zhí)行sql語句時出現(xiàn)提示”無效的描述器索引”????

?

5.執(zhí)行SQL語句時候老是出錯,一定要完成增刪改查

總結

以上是生活随笔為你收集整理的ODBC学习(一)基本理论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。