使用ODBCAPI連接數(shù)據(jù)庫_第1頁
使用ODBCAPI連接數(shù)據(jù)庫_第2頁
使用ODBCAPI連接數(shù)據(jù)庫_第3頁
使用ODBCAPI連接數(shù)據(jù)庫_第4頁
使用ODBCAPI連接數(shù)據(jù)庫_第5頁
已閱讀5頁,還剩19頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、主要內(nèi)容: Ø Ø ODBC API的體系結(jié)構(gòu) Ø Ø 使用ODBC API開發(fā)數(shù)據(jù)庫應(yīng)用程序的一般步驟 Ø Ø 使用函數(shù)SQLAllocHandle分配句柄 Ø Ø 使用函數(shù)SQLConnect、SQLDriverConnect、SQLBrowseConnect連接數(shù)據(jù)源 Ø Ø 使用函數(shù)SQLPrepare和SQLExecute執(zhí)行SQL語句 Ø Ø 使用函數(shù)SQLBindCol()綁定數(shù)據(jù)庫字段 Ø Ø 使用函數(shù)SQLGetDiagRec和SQLGe

2、tDiagField處理錯(cuò)誤 Ø Ø 使用函數(shù)SQLFetch移動(dòng)數(shù)據(jù)庫記錄指針 Ø Ø 使用ODBC API 進(jìn)行事務(wù)處理 Ø Ø 使用函數(shù)SQLDisconnect斷開數(shù)據(jù)源的連接 目錄ODBC API 基礎(chǔ)3ODBC API句柄3ODBC數(shù)據(jù)類型5ODBC診斷5使用ODBC API變成建立應(yīng)用程序7ODBC API編程模型概述7連接數(shù)據(jù)庫10準(zhǔn)備并執(zhí)行SQL語句14獲取記錄集16記錄的添加、刪除和更新18錯(cuò)誤處理20事務(wù)處理21斷開數(shù)據(jù)源連接并釋放環(huán)境句柄23ODBC API 基礎(chǔ)ODBC API句柄ODBC

3、 API 實(shí)現(xiàn)數(shù)據(jù)庫操作的手段是句柄。在ODBC中,使用不同的句柄(HANDLE)來標(biāo)志環(huán)境(environment)、連接(Connection)、語句(statement)、描述符(description)等。句柄是一個(gè)應(yīng)用程序變量,系統(tǒng)用它來存儲(chǔ)關(guān)于應(yīng)用程序的上下文信息和應(yīng)用程序所用到的一些對(duì)象。 1、 環(huán)境句柄 環(huán)境是存取數(shù)據(jù)的全局性背景,與環(huán)境相關(guān)的是全局的所有信息。例如:環(huán)境狀態(tài)、當(dāng)前環(huán)境狀態(tài)診斷、當(dāng)前在環(huán)境上分配的連接句柄、每個(gè)環(huán)境屬性的當(dāng)前設(shè)置。 在實(shí)現(xiàn)ODBC的一段代碼(Driver Manager或者驅(qū)動(dòng)程序)中,環(huán)境句柄標(biāo)識(shí)包含這個(gè)信息的結(jié)構(gòu)。環(huán)境句柄在ODBC應(yīng)用程序中

4、不經(jīng)常用。他們經(jīng)常用來調(diào)用SQLDataSources和SQLDrivers,又是用來調(diào)用函數(shù)SQLAllocHandle、SQLEndTran、SQLFreeHandle、SQLGetDiagField和SQLGetDiagReg。 環(huán)境句柄ODBC中整個(gè)上下文的句柄,使用ODBC的每個(gè)程序從創(chuàng)建環(huán)境句柄開始、以釋放環(huán)境句柄結(jié)束。所有其他的句柄都由環(huán)境句柄的上下文來管理。環(huán)境句柄在每個(gè)應(yīng)用程序中只能創(chuàng)建一個(gè)。 2、 連接句柄 一個(gè)連接包含一個(gè)驅(qū)動(dòng)程序和一個(gè)數(shù)據(jù)源。連接句柄標(biāo)識(shí)每個(gè)連接。連接句柄定義使用哪個(gè)驅(qū)動(dòng)程序和該驅(qū)動(dòng)程序使用的數(shù)據(jù)源。在執(zhí)行一段ODBC(Driver Manager或者驅(qū)

5、動(dòng)程序)的代碼中,連接句柄標(biāo)志一個(gè)包含連接信息的結(jié)構(gòu)。比如:連接狀態(tài)、當(dāng)前連接層診斷、語句句柄和當(dāng)前連接上分配的描述符、每個(gè)連接屬性的當(dāng)前設(shè)置。 如果驅(qū)動(dòng)程序支持多個(gè)同時(shí)連接,ODBC并不阻止多個(gè)同時(shí)的連接。因此,在特定的ODBC環(huán)境中,多個(gè)連接句柄可能指向不同的驅(qū)動(dòng)程序和數(shù)據(jù)源、相同的驅(qū)動(dòng)程序和不同的數(shù)據(jù)源甚至是與相同的驅(qū)動(dòng)程序和數(shù)據(jù)源的多個(gè)連接。一些驅(qū)動(dòng)程序限制他們支持的活動(dòng)連接數(shù)目,SQLGetInfo中的SQL_MAX_DRIVER_CONNECTIONS選項(xiàng)可指定一個(gè)特定的驅(qū)動(dòng)程序支持多少個(gè)活動(dòng)連接。與數(shù)據(jù)源進(jìn)行連接(SQLConnect、SQLDriverConnect或SQLBr

6、owseConnect)、從數(shù)據(jù)源上斷開(SQLDisconnect)、獲取驅(qū)動(dòng)程序及數(shù)據(jù)源信息(SQLGetInfo)、檢索診斷(SQLGetDiagField和SQLGetDiagRec)和執(zhí)行事務(wù)(SQLEndTran)時(shí),都需要使用連接句柄。當(dāng)設(shè)置和獲取連接屬性(SQLSetConnectAttr)及獲取SQL語句內(nèi)部格式(SQLNativeSql)時(shí),也使用它們。 在應(yīng)用程序中,可在任何適當(dāng)?shù)臅r(shí)候連接或脫離數(shù)據(jù)源,但不要輕易的建立或脫離連接。 3、 語句句柄 一個(gè)語句不只是一個(gè)SQL語句,它包含所有與那個(gè)SQL語句相關(guān)的信息,如任何由語句和語句執(zhí)行中使用的參數(shù)建立的結(jié)果集。一個(gè)語句甚

7、至不需要應(yīng)用程序的SQL語句。例如,當(dāng)在一個(gè)語句上執(zhí)行如SQLTables這樣的編目函數(shù)時(shí),它執(zhí)行返回表名列表的預(yù)定義SQL語句。 每個(gè)語句由語句句柄標(biāo)識(shí)。一個(gè)語句與單個(gè)的連接相關(guān),并且在那個(gè)連接上可能有多個(gè)語句。一些驅(qū)動(dòng)程序限制它們支持活動(dòng)語句的數(shù)目,在SQLGetInfo中SQL_MAX_CONCURRENT_ACTIVITIES選項(xiàng)指定一個(gè)驅(qū)動(dòng)程序在單個(gè)的連接上支持多少個(gè)活動(dòng)的語句。如果它的結(jié)果是未確定的,那么語句被定義成“活動(dòng)的”,其結(jié)果既不是結(jié)果集,也不是受INSERT、UPDATE、或DELETE語句影響的行數(shù),或者用多個(gè)調(diào)用把數(shù)據(jù)發(fā)送到SQLPutData。 在實(shí)現(xiàn)ODBC(Dr

8、iver Manager或驅(qū)動(dòng)程序)的一段代碼中,語句句柄標(biāo)識(shí)一個(gè)包含語句信息的結(jié)構(gòu),如:語句狀態(tài)、當(dāng)前語句層診斷、應(yīng)用程序變量綁定到語句參數(shù)和結(jié)果集列的地址、每個(gè)語句屬性的當(dāng)前設(shè)置。 語句句柄在大多數(shù)ODBC函數(shù)中使用,它們用于函數(shù)綁定參數(shù)及結(jié)果集列(SQLBindParameter和SQLBindCol)、準(zhǔn)備執(zhí)行語句(SQLPrepare、SQLExecute和SQLExecDirect)、檢索元數(shù)據(jù)(SQLColAttribute和SQLDescribeCol)、取結(jié)果(SQLFetch)和檢索診斷(SQLGetDiagField和SQLGetDiagRec)。它們還在編目函數(shù)(SQL

9、Columns,SQLTables等)和其他一些函數(shù)中使用。語句句柄使用SQLAllocHandle分配,使用SQLFreeHandle釋放。 4、 描述符句柄 從應(yīng)用程序或驅(qū)動(dòng)程序來看,描述符就是描述SQL語句的參數(shù)或結(jié)果集列的元數(shù)據(jù)集合。因此,描述符可用來擔(dān)當(dāng)如下4種角色: 1) 應(yīng)用程序參數(shù)描述符(APD):包含綁定到SQL語句中參數(shù)的應(yīng)用程序緩沖區(qū)的信息,如它們的地址、長度和C數(shù)據(jù)類型。 2) 實(shí)現(xiàn)參數(shù)描述符(IPD):包含關(guān)于SQL語句中參數(shù)的信息,如它們的SQL數(shù) 據(jù)類型、長度、和可控性(nullability)。 3) 應(yīng)用程序行描述符(ARD):包含綁定到結(jié)果集列的應(yīng)用程序緩沖

10、區(qū)的信息, 如它們的地址、長度和C數(shù)據(jù)類型。 4) 實(shí)現(xiàn)行描述符(IRD):包含結(jié)果集中列的信息,如它們的SQL數(shù)據(jù)類型、長 度、和可控性。 四種描述符(一種承擔(dān)一個(gè)角色)在分配語句時(shí)自動(dòng)分配,且總是與那條語句相關(guān)。稱為自動(dòng)分配描述符。應(yīng)用程序還可用SQLAllocHandle分配描述符,稱為顯示分配描述符。它們根據(jù)連接進(jìn)行分配,并且可以與那個(gè)連接上的一條或多條語句關(guān)聯(lián),來履行那些語句上的APD或ARD的職責(zé)。 應(yīng)用程序可完成ODBC中的大多數(shù)操作,而不明確使用描述符。然而,描述符可以為有些操作提供方便的快捷方式。例如,假設(shè)一個(gè)應(yīng)用程序想從兩套不同的緩沖區(qū)插入數(shù)據(jù)。要用第一套緩沖區(qū),它會(huì)反復(fù)調(diào)

11、用SQLBindParameter來把它們綁定至INSERT語句的參數(shù)中,然后再執(zhí)行該語句。要使用第二套緩沖區(qū),它就會(huì)重復(fù)這個(gè)過程。另一種方法就是在一個(gè)描述符中建立起對(duì)第一套緩沖區(qū)的綁定,在另一個(gè)描述符中建立對(duì)第二套緩沖區(qū)的綁定。要在兩套綁定集間切換,只需調(diào)用SQLSetStmtAttr,并把正確的描述符作為APD與語句聯(lián)系起來即可。 ODBC數(shù)據(jù)類型 ODBC使用兩套數(shù)據(jù)類型:SQL數(shù)據(jù)類型和C數(shù)據(jù)類型。SQL數(shù)據(jù)類型用于數(shù)據(jù)源,而C數(shù)據(jù)類型用于應(yīng)用程序的C代碼。 1、 SQL數(shù)據(jù)類型 SQL數(shù)據(jù)類型是在數(shù)據(jù)源中保存的數(shù)據(jù)類型。每個(gè)數(shù)據(jù)源都定義了它自己的SQL數(shù)據(jù)類型。ODBC定義類型標(biāo)識(shí)符

12、并且描述可能映射為每一種類型標(biāo)識(shí)符的SQL數(shù)據(jù)類型的一種特征。在基本數(shù)據(jù)源中,每一種數(shù)據(jù)類型如何映射為ODBC的SQL類型標(biāo)識(shí)符是由驅(qū)動(dòng)程序制定的。 ODBC中定義的常用SQL數(shù)據(jù)類型如表所示,此處列出了部分常用的類型,詳細(xì)資料參見ODBC的技術(shù)手冊(cè):SQL類型標(biāo)識(shí)SQL類型舉例SQL_CHARCHAR(n) SQL_VACHAR VACHAR(n)SQL_LONGVACHAR LONG VACHARSQL_WCHARWCHAR(n)2、 C數(shù)據(jù)類型 ODBC定義了由應(yīng)用程序變量及其相應(yīng)的數(shù)據(jù)標(biāo)識(shí)符所使用的C數(shù)據(jù)類型。在其他的事情中,它們也用于綁定至結(jié)果集列和語句參數(shù)的緩沖區(qū)。ODBC還定義了

13、一個(gè)從每個(gè)數(shù)據(jù)類型到一個(gè)C數(shù)據(jù)類型的默認(rèn)映射。要使用默認(rèn)映射,應(yīng)用程序可指定SQL_C_DEFAULT類型標(biāo)識(shí)符。但是,出于互操作性的原因,不主張使用這個(gè)標(biāo)識(shí)符。在ODBC 1.x版本中定義的所有整數(shù)C數(shù)據(jù)類型都是帶符號(hào)的。在ODBC 2.0中添加了不帶符號(hào)的C數(shù)據(jù)類型及其相應(yīng)的數(shù)據(jù)標(biāo)識(shí)符。 ODBC中定義的常用C數(shù)據(jù)類型如表所示,此處列出了部分常用的類型,詳細(xì)資料參見ODBC的技術(shù)手冊(cè): C類型標(biāo)識(shí)ODBC C類型定義C類型SQL_C_CHARSQLCHARUnsigned char *SQL_C_SSHORTSQLSMALLINTShort intSQL_C_USHORTjSQLUSMAL

14、LINTUnsigned short intSQL_C_SLONGjSQLINTEGERLong intODBC診斷 為了在程序開發(fā)過程中調(diào)試程序,發(fā)現(xiàn)程序錯(cuò)誤,ODBC API 通過兩種方式返回有關(guān)ODBC API函數(shù)執(zhí)行的信息:返回碼和診斷記錄。返回碼返回函數(shù)執(zhí)行的返回值,說明函數(shù)執(zhí)行成功與否;診斷記錄說明函數(shù)執(zhí)行的詳細(xì)信息。 1、 返回碼(Return Code) 每一個(gè)ODBC API函數(shù)都返回一個(gè)代碼返回碼,指示函數(shù)執(zhí)行的成功與否。如果函數(shù)調(diào)用成功,返回碼為SQL_SUCCESS(指示可通過診斷記錄獲取相關(guān)操作的詳細(xì)信息)或SQL_SUCCESS_WITH_INFO(指示應(yīng)用程序執(zhí)行

15、結(jié)果帶有警告信息,可通過診斷記錄獲取詳細(xì)的信息)。如果函數(shù)調(diào)用失敗,返回碼為SQL_ERROR。 下面一段代碼根據(jù)函數(shù)SQLFetch()執(zhí)行的返回碼,判斷函數(shù)執(zhí)行的成功與否,從而據(jù)此進(jìn)行相應(yīng)的處理: SQLRETURN rtcode; SQLHSTMT hstmt; While(rtcode = SQLFetch(hstmt) != SQL_NO_DATA) If(rtcode = SQL_SUCCESS_WITH_INFO) /顯示警告信息 else /顯示出錯(cuò)信息 break; /函數(shù)調(diào)用成功 如果程序執(zhí)行錯(cuò)誤,返回碼為SQL_INVALID_HANDLE,程序無法執(zhí)行,而其他的返回碼都

16、帶有程序執(zhí)行信息。 2、 診斷記錄 每個(gè)ODBC API函數(shù)都能產(chǎn)生一系列的反應(yīng)操作信息的診斷記錄,這些診斷記錄都放在相關(guān)聯(lián)的ODBC句柄中,直到下一個(gè)使用同一個(gè)句柄的函數(shù)調(diào)用,該診斷記錄一直存在。診斷記錄的大小沒有限制。 診斷記錄有兩種:頭記錄(Head Record)和狀態(tài)記錄(Status Record)。頭記錄是第一版權(quán)記錄(Record0),后面的記錄為狀態(tài)記錄。診斷記錄有許多的域組成,這些域在頭記錄和狀態(tài)記錄中是不同的。 可以用SQLGetDiagField函數(shù)獲取診斷記錄中的特定的域,另外,可以使用SQLGetDiagRec()函數(shù)獲取診斷記錄中一些常用的域,如SQLSTATE、

17、原始錯(cuò)誤號(hào)等。 (1) 頭記錄 頭記錄的各個(gè)域中包含了一個(gè)函數(shù)執(zhí)行的通用信息,無論函數(shù)執(zhí)行成功與否,只要不返回SQL_INVALID_HANDLE,都會(huì)生成頭記錄。 (2) 狀態(tài)記錄 狀態(tài)記錄中的每個(gè)域包含了驅(qū)動(dòng)管理器、ODBC驅(qū)動(dòng)程序或數(shù)據(jù)源返回的特定的錯(cuò)誤或警告信息,包括SQLSTATE、原始錯(cuò)誤碼、診斷信息、列號(hào)和行號(hào)等。只有函數(shù)執(zhí)行返回SQL_ERROR、SQL_STILL_EXEUTING、SQL_SUCCESS_WITH_INFO、SQL_NEED_DATA或SQL_NO_DATA時(shí),才會(huì)生成診斷記錄。 (3) 使用SQLGetDiagRec和SQLGetDiagField 應(yīng)用程

18、序可以調(diào)用SQLGetDiagRec和SQLGetDiagField函數(shù)獲取診斷信息。對(duì)于給定的句柄,這兩個(gè)函數(shù)返回最近使用句柄的函數(shù)的診斷信息。當(dāng)有使用該句柄的函數(shù)執(zhí)行時(shí),句柄記錄所記錄的原有的診斷信息被覆蓋。如果函數(shù)執(zhí)行后產(chǎn)生多個(gè)狀態(tài)記錄,程序必須多次調(diào)用這兩個(gè)函數(shù)以獲取信息。例如,下面的代碼提示符提供給用戶使用SQL語句并執(zhí)行它。如果返回一些真消息,則它調(diào)用SQLGetDiagField來取得狀態(tài)記錄書并調(diào)用SQLGetDiagRec來從那些記錄中取得SQLSTATE、本地錯(cuò)誤代碼、診斷消息:  SQLCHAR sqlState6, SQLStmt

19、100, MsgSQL_MAX_MESSAGE_LENGTH; SQLINTRGER NativeError; SQLSMALLINT I,MsgLen; SQLRETURN rc1, rc2; SQLHSTME Hstmt;  /Prompt the user for an SQL statement GetSQLStmt(SQLStmt);  /執(zhí)行SQL語句返回錯(cuò)誤結(jié)果 

20、rc1 = SQLExecDirect(hstmt, SQLStmt, SQL_NTS); if(rc1 = SQL_SUCCESS_WITH_INFO) | (rc1 = SQL_ERROR)  /得到狀態(tài)記錄  i = 1; while(rc2 = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, SqlState, &Na

21、tiveError, Msg, sizeof(Msg), &MsgLen) != SQL_NO_DATA)   DisplayError(SqlState, NativeError, Msg, MsgLen); i+;    if(rc1 = SQL_SUCCESS) | (rc1 = SQL_SUCCESS_WITH_INFO)  /如果必要就處理

22、結(jié)果使用ODBC API變成建立應(yīng)用程序ODBC API編程模型概述使用ODBC API編寫的程序運(yùn)行時(shí)相對(duì)要簡潔、高效。一般,編寫ODBC程序主要有以下幾個(gè)步驟: l l 為ODBC分配環(huán)境句柄l 分配一個(gè)連接句柄 l l 用SQL命令分配一個(gè)語句句柄 l l 執(zhí)行該命令返回結(jié)果集 l l 斷開同數(shù)據(jù)源的連接 l l 釋放ODBC環(huán)境 為了更清楚的闡述ODBC API的調(diào)用步驟以及涉及到的重要函數(shù),總結(jié)了一 個(gè)表來說明ODBC API應(yīng)用的結(jié)構(gòu): SQLAllocHandle(ENV)SQLSetEnvAttrSQLAllocHandle(DBC)SQLConnectSQ

23、LSetConnectAttrSQLGetInfo SQLAllocHandle(STMT)SQLSetStmtAttrODBC初始化函數(shù)SQLExecDirectOR SQLPrepareSQLExecute使用ODBC API 檢索數(shù)據(jù)Select OR Update/Delete/InsertSQLNumResultColsSQLBindCOL SQLFetchSQLGetDataSQLCloseCursor執(zhí)行SQL語句使用結(jié)果集SQLFreeHandle(STMT)SQLDisconnect SQLFreeHandle(DBC)SQLFreeHandle(ENV)釋放空間所有ODBC

24、應(yīng)用程序都必須遵循上圖的通用ODBC API調(diào)用 注冊(cè)數(shù)據(jù)源(Access數(shù)據(jù)庫employers.mdb,其中只有一張表emp,包含三個(gè)字段:職工號(hào)<數(shù)字,關(guān)鍵字>、職工名稱<文本>、工作<文本>) /添加ODBC數(shù)據(jù)源 void CDemo1App:SetODBCSource() CString strAccessPath = m_strExePath + “employers.mdb”; int iLen = strAccessPath.GetLength(); char cpConfigMAX_PATH; /構(gòu)造注冊(cè)字符串 strcpy(cpConf

25、ig,“DSN = daliu0”); strcpy(cpConfig + 10, “DBC=”); strcpy(cpConfig + 14, strAccessPath); strcpy(cpConfig + 14 + iLen, “0”); strcpy(cpConfig + 15 + iLen, “DEFAULTDIR = ”); strcpy(cpConfig + 15 + iLen + 11, m_strExePath); strcpy(cpConfig + 25 + iLen + m_strExePath.GetLength(), “00 ”); /注冊(cè)數(shù)據(jù)源 if(!SQLCo

26、nfigDataSource(NULL, ODBC_ADD_SYS_DSN, “Microsoft Access Driver(*.mdb)0”, cpConfig) /AfxMessageBox(“add odbc source failed!”); 連接數(shù)據(jù)庫 連接數(shù)據(jù)庫包括初始化環(huán)境句柄、初始化連接句柄以及連接數(shù)據(jù)源等幾個(gè)步驟。 1、 初始化環(huán)境句柄 (1) 分配環(huán)境句柄 對(duì)于任何ODBC應(yīng)用程序來說,第一步的工作是裝在驅(qū)動(dòng)程序管理器,然后初始化ODBC環(huán)境,分配句柄 首先聲明一個(gè)SQLHENV類型的變量,然后調(diào)用SQLAllocHandle,向其中傳遞分配的SQLHENV類型的變量地址

27、和SQL_HANDLE_ENV選項(xiàng),代碼如下: /分配環(huán)境句柄m_retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) AfxMessageBox(“分配環(huán)境句柄失敗”); return FALSE; 其中:m_henv是要分配的環(huán)境句柄,m_retcode是返回碼。 執(zhí)行該調(diào)用語句后,驅(qū)動(dòng)程序分配一個(gè)結(jié)構(gòu),該結(jié)構(gòu)中存放環(huán)境變量,然后返回對(duì)應(yīng)于該環(huán)境的環(huán)

28、境句柄。 一個(gè)應(yīng)用程序?qū)?yīng)于一個(gè)環(huán)境,但是同一個(gè)環(huán)境可以用于不同數(shù)據(jù)源的連接,可以使用多個(gè)線程,應(yīng)用程序完成數(shù)據(jù)訪問任務(wù),應(yīng)調(diào)用函數(shù)SQLFreeHandle()函數(shù)釋放當(dāng)前分配的環(huán)境。 (2) 設(shè)置環(huán)境屬性 應(yīng)用程序在完成環(huán)境的分配后,接著調(diào)用函數(shù)SQLSetEnvAttr設(shè)置環(huán)境屬性,注冊(cè)O(shè)DBC的版本號(hào),說明應(yīng)用程序所遵從的標(biāo)準(zhǔn)是ODBC 2.x還是ODBC 3.x,相關(guān)代碼如下所示。使用不同的版本,相同的參數(shù)作用會(huì)不相同,具體的說明參見MSDN。 /*設(shè)置ODBC版本的環(huán)境屬性*/ m_retcode=SQLSetEnvAttr(m_henv,SQL_ATTR_ODBC_VERSION

29、,(void*)SQL_OV_ODBC3, 0); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV, “設(shè)置ODBC版本號(hào)時(shí)失敗”); return FALSE; 其中m_henv是環(huán)境句柄,m_retcode是返回碼,ReportError是一個(gè)處理錯(cuò)誤的函數(shù)。 2、 初始化連接句柄 (1) 分配連接句柄 分配環(huán)境句柄之后,在建立至數(shù)據(jù)源的連接之前,必須分配一個(gè)連接句柄,每一個(gè)到數(shù)據(jù)源的連接對(duì)應(yīng)于一個(gè)連接句柄。 首先,

30、程序定義一個(gè)SQLHDBC類型的變量,用于存放連接句柄,然后調(diào)用SQLAllocHandle函數(shù)分配句柄。 /分配連接句柄 m_retcode = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc);if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV, “分配連接句柄失?。 ?; return FALSE; 其中m_henv是環(huán)境句柄,m_hdbc是要分配的連接句柄,m_r

31、etcode是返回碼 (2) 設(shè)置連接屬性 連接屬性表示了一個(gè)連接的特性,如登錄等待時(shí)間、使用的光標(biāo)庫等。 所有的連接屬性都有默認(rèn)值,也可以通過調(diào)用函數(shù)SQLSetConnectAttr()設(shè)置,調(diào)用函數(shù)SQLGetConnectAttr()可獲取這些連接屬性的當(dāng)前設(shè)置值,這兩個(gè)函數(shù)定義如下: SQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTRGER StringLength ); SQLRETURN SQLGetConnectAttr( SQLHDBC

32、ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLengthPtr ); 3、 連接數(shù)據(jù)源 完成連接屬性的設(shè)置之后,就可以建立到數(shù)據(jù)源的連接了。對(duì)于不同的程序和用戶接口,可以用不同的函數(shù)建立連接:SQLConnect、SQLDriverConnect、SQLBrowseConnect (1) SQLConnect 該函數(shù)提供了最為直接的程序控制方式,只要提供數(shù)據(jù)源名稱、用戶ID和口令,就可以進(jìn)行連接了。其定義如下: SQLRETURN

33、SQLConnect( SQLHDBC ConnectionHandle, /連接句柄 SQLCHAR *ServerName, /數(shù)據(jù)源名稱 SQLSMALLINT NameLength1, /數(shù)據(jù)源名稱長度SQLCHAR *UserName, /用戶ID SQLSMALLINT NameLength2, /用戶ID長度 SQLCHAR *Authentication, /用戶口令 SQLSMALLINT NameLength3 /用戶口令長度 ); /連接數(shù)據(jù)源 m_retcode = SQLConnect(m_hdbc, (SQLCHAR *)cpServerName, SQL_NTS,

34、 (SQLCHAR *)cpUserName, SQL_NTS, (SQLCHAR *)cpPassword, SQL_NTS); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_hdbc, SQL_HANDLE_DBC, “連接數(shù)據(jù)庫失敗!”); return FALSE; (2) SQLDriverConnect 該函數(shù)用一個(gè)連接字符串建立至數(shù)據(jù)源的連接,他可以提供比SQLConnect函數(shù)的3個(gè)參數(shù)更多的信息,可以讓用戶輸入必要的連接信息,使用系統(tǒng)中還沒有

35、定義的數(shù)據(jù)源。 如果連接建立,該函數(shù)會(huì)返回完整的連接字符串,應(yīng)用程序可以使用連接字符串建立額外的連接,其定義如下: SQLRETURN SQLDriverConnect( SQLHDBC ConnectionHandle; /連接句柄 SQLHWND WindowHandle; /窗口句柄,程序可以用父窗口的句柄或用空指針 SQLCHAR *InConnectionString; /一個(gè)指向連接字符串的指針 SQLSMALLINT StringLength1, /連接字符串長度 SQLCHAR *OutConnectionString; /一個(gè)指向連接字符串的指針 SQLSMALLINT Bu

36、fferLength; /存放連接字符串的緩沖區(qū)的長度 SQLSMALLINT *StringLength2Ptr; /返回的連接字符串中的字符數(shù) SQLUSMALLINT DriverCompletion /額外的連接信息,可能的取值:SQL_DRIVER_PROMPT、SQL_DRIVER_COMPLETE、SQL_DRIVER_COMPLETE_REQUIRED、 SQL_DRIVER_NOPROMPT); (3) SQLBrowseConnect 函數(shù)SQLBrowseConnect支持以一種迭代的方式獲取到數(shù)據(jù)源的連接,直到最后建立連接。它基于客戶機(jī)/服務(wù)器體系結(jié)構(gòu),因此本地?cái)?shù)據(jù)庫(

37、如Microsoft Access)不支持該函數(shù)。 一般,只提供部分連接信息,如果足以建立到數(shù)據(jù)源的連接,則成功建立連接,否則返回SQL_NEED_DATA,并在OutConnectionString參數(shù)中返回所需要的信息。其定義如下: SQLRETURN SQLBrowseConnect( SQLHDBC ConnectionHandle, /連接句柄 SQLCHAR *InConnectionString, /指向輸入字符串的指針 SQLSMALLINT StringLength1, /輸入字符串的指針長度 SQLCHAR *OutConnectionString, /指向輸出字符串的指針

38、 SQLSMALLINT BufferLength, /存放輸出字符串的緩沖區(qū)的長度 SQLSMALLINT *StringLength2Ptr /實(shí)際返回的字符串的長度 ); 連接數(shù)據(jù)庫的完整代碼: BOOL CMyODBC:ConnectDB(const char *cpServerName, const char *cpUserName, const char *cpPassword) /分配環(huán)境句柄 m_retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv); if(m_retcode != SQL_

39、SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ) AfxMessageBox(“分配環(huán)境句柄失??!”); return FALSE; /*Set the ODBC version environment attribute*/ m_retcode = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WIT

40、H_INFO) ReportError(m_henv, SQL_HANDLE_ENV, “設(shè)置odbc版本號(hào)時(shí)失??!”); return FALSE; /*分配連接句柄*/ m_retcode = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV, “分配連接句柄失?。 ?;return FALSE; /*連接數(shù)據(jù)庫*

41、/ m_retcode = SQLConnect(m_hdbc, (SQLCHAR *)cpServerName, SQL_NTS, (SQLCHAR *)cpUserName, SQL_NTS, (SQLCHAR *)cpPassword, SQL_NTS); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) eportError(m_hdbc, SQL_HANDLE_DBC, “連接數(shù)據(jù)庫失敗!”); return FALSE; return TRUE; 準(zhǔn)備并執(zhí)行SQL語句 1、 構(gòu)造

42、SQL語句 可以通過3種方式構(gòu)造SQL語句: ² ² 在程序開發(fā)階段確定:具有易于實(shí)現(xiàn)且可在程序編碼時(shí)進(jìn)行測(cè)試的優(yōu)點(diǎn) ²² 在運(yùn)行時(shí)確定:提供了極大靈活性,但給程序帶來了困難,卻需要更多的處 理時(shí)間 ² ² 由用戶輸入SQL語句:極大的增強(qiáng)了程序的功能,但是程序必須提供有好的 程序界面,且對(duì)用戶輸入的語句執(zhí)行一定程序的語法檢查,能夠報(bào)告用戶錯(cuò)誤。 2、 執(zhí)行SQL語句 (1) 分配語句句柄 語句句柄為ODBC驅(qū)動(dòng)程序管理器提供數(shù)據(jù)結(jié)構(gòu),并跟蹤SQL語句的執(zhí)行機(jī)器返回的結(jié)果,語句句柄是通過調(diào)用SQLAllocHandle函數(shù)分配的。下面

43、的代碼聲明了一個(gè)存放語句句柄的變量m_hstmt,在函數(shù)中提供該變量的地址指針、所使用的連接句柄m_hdbc以及選項(xiàng)SQL_HANDLE_STMT: m_retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_hdbc, SQL_HANDLE_DBC, “分配語句句柄失敗,不能執(zhí)行”); return FALSE; 函數(shù)SQLGetStmrr

44、Attr()和SQLSetStmrrAttr()用來獲取和設(shè)置一個(gè)語句句柄的選項(xiàng),使用方式同前面的SQLGetConnectAttr()和SQLSetConnectAttr()函數(shù)相同。當(dāng)一個(gè)語句句柄使用完成后,調(diào)用函數(shù)SQLFreeHandle()釋放句柄。 (2) SQLExecDirect() SQLExecDirect()函數(shù)直接執(zhí)行SQL語句,對(duì)于只執(zhí)行一次的SQL語句來說,該函數(shù)是執(zhí)行最快的方法,其定義如下: SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, /語句句柄 SQLCHAR *StatementText, /要執(zhí)行的SQ

45、L語句 SQLINTEGER TextLength /SQL語句的長度 );Demo1中使用該函數(shù)執(zhí)行SQL語句的代碼: m_retcode = SQLExecDirect(m_hstmt, (unsigned char *)cpSql, SQL_NTS); if(m_retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_hstmt, SQL_HANDLE_STMT, “執(zhí)行SQL語句失敗”); SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt); m_

46、hstmt = NULL; return FALSE; (3) SQLPrepare()和SQLExecute() 對(duì)于需要多次執(zhí)行的SQL語句來說,除了使用SQLExecDirect函數(shù)之外,也可以在執(zhí)行SQL語句之前,先調(diào)用函數(shù)SQLPrepare()準(zhǔn)備SQL語句的執(zhí)行。對(duì)于使用參數(shù)的語句,這可大大提高程序的執(zhí)行速度。而函數(shù)SQLExecute()用來執(zhí)行一個(gè)準(zhǔn)備好的語句,當(dāng)語句中有參數(shù)時(shí),用當(dāng)前綁定的參數(shù)變量的值。其定義如下: SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, /語句句柄 SQLCHAR *StatementText, /要執(zhí)

47、行的SQL語句 SQLINTEGER TextLength /SQL語句的長度 ); SQLRETURN SQLExecute(SQLHSTMT StatementHandle); /語句句柄 (4) 使用參數(shù) 使用參數(shù)可以使一條SQL語句多次執(zhí)行,得到不同的結(jié)果,如下面的一條SQL語句: INSERT INTO EMP(職員號(hào),職工名稱,工作) VALUES(?,?,?) 該語句將向表emp中加入一條記錄,通過參數(shù)替換(將句中問號(hào)出現(xiàn)的地方以相應(yīng)的參數(shù)值替換),可以在程序運(yùn)行的時(shí)候動(dòng)態(tài)的添加多條記錄。 SQL語句執(zhí)行時(shí),參數(shù)標(biāo)識(shí)符(“?”)綁定程序中的變量,通過參數(shù)就可以在程序執(zhí)行時(shí)動(dòng)態(tài)的將

48、值傳入SQL語句。 函數(shù)SQLBindParameter()負(fù)責(zé)為參數(shù)定義變量,將一段SQL語句中的一個(gè)參數(shù)標(biāo)識(shí)符(“?”)綁定在一起,實(shí)現(xiàn)參數(shù)值的傳遞,其定義如下: SQLRETURN SQLBindParameter( SQLHSTMT StatementHandle, /語句句柄 SQLUSMALLINT ParameterNumber, /綁定的參數(shù)在SQL語句中的序號(hào),在SQL 中,所有參數(shù)從左到右依次編號(hào)(從1開 始)。SQL語句執(zhí)行之前,應(yīng)該為每個(gè)參數(shù)調(diào)用函數(shù)SQLBindParameter綁定到某個(gè)程序變量。 SQLSMALLINT InputOutputType, /參數(shù)類型

49、,可為SQL_PARA_INPUT、SQL_PARAM_INPUT_OUTPUT、SQL_PARAM_OUTPUT SQLSMALLINT ValueType, /參數(shù)的C數(shù)據(jù)類型 SQLSMALLINT ParameterType, /參數(shù)的SQL數(shù)據(jù)類型 SQLUINTEGER ColumnSize, /參數(shù)的大小 SQLSMALLINT DecimalDigits, /參數(shù)的精度 SQLPOINTER ParameterValuePtr, /指向程序中存放參數(shù)值的緩沖區(qū)的指針 SQLINTEGER BufferLength, /程序中存放參數(shù)值的緩沖區(qū)的字節(jié)數(shù) SQLINTEGER *S

50、trLen_or_IndPtr /指向存放參數(shù)ParameterValuePtr的緩沖區(qū)指針 ); 獲取記錄集 查詢記錄集是數(shù)據(jù)源上滿足一定條件的數(shù)據(jù)記錄的集合,在概念上,可以看成是一個(gè)臨時(shí)存放返回結(jié)果的表。記錄集可以是空。在用SQLExecDirect等函數(shù)執(zhí)行SQL語句后,就可以從數(shù)據(jù)源中取回記錄集。 1、 綁定列 從數(shù)據(jù)源取回的數(shù)據(jù)存放在應(yīng)用程序定義的變量中,因此,必須首先分配與記錄集中字段相對(duì)應(yīng)的變量,然后通過函數(shù)SQLBindCol將記錄字段同程序變量綁定在一起。對(duì)于長記錄字段,可以通過調(diào)用函數(shù)SQLGetData()直接取回?cái)?shù)據(jù)。 綁定字段可以根據(jù)自己的需要全部綁定,也可以綁定其中

51、的某幾個(gè)字段。 記錄集中的字段可以在任何時(shí)候綁定,但是,新的綁定只有當(dāng)下一次從數(shù)據(jù)源中取數(shù)據(jù)時(shí)執(zhí)行的操作才有效,而不會(huì)對(duì)已經(jīng)取回的數(shù)據(jù)產(chǎn)生影響。 通過調(diào)用函數(shù)SQLBindCol將其變量地址賦值為NULL,可以結(jié)束對(duì)一個(gè)記錄字段的綁定;通過調(diào)用函數(shù)SQLFreeStmt,將其中的選項(xiàng)設(shè)為SQL_UNBIND,或者是直接釋放句柄,都會(huì)結(jié)束所有記錄字段的綁定。函數(shù)SQLBindCol的定義如下: SQLRETURN SQLBindCol( SQLHSTMT StatementHandle, /語句句柄 SQLUSMALLINT ColumnNumber, /標(biāo)識(shí)要綁定的列號(hào)。數(shù)據(jù)列號(hào)從0開始升序排

52、列,其中第0列用作書簽,則列號(hào)從1開始 SQLSMALLINT TargetType, /數(shù)據(jù)類型 SQLPOINTER TargetValuePtr, /綁定到數(shù)據(jù)字段的緩沖區(qū)的地址 SQLINTEGER BufferLength, /緩沖區(qū)長度 SQLINTEGER *StrLen_or_IndPtr /指向綁定數(shù)據(jù)列使用的長度的指針 ); 2、 SQLFetch() 函數(shù)SQLFetch用于將記錄集中的下一行變?yōu)楫?dāng)前行,并把所有捆綁過的數(shù)據(jù)字段的數(shù)據(jù)拷貝到相應(yīng)的緩沖區(qū),其定義如下:SQLRETURN SQLFetch(SQLHSTMT StatementHandle); /Stateme

53、ntHandle:語句句柄 3、 光標(biāo) 應(yīng)用程序獲取數(shù)據(jù)是通過光標(biāo)(Cursor)來實(shí)現(xiàn)的,在ODBC中,主要有3種類型的光標(biāo): (1) 單向光標(biāo) 單向光標(biāo)只能向前移動(dòng),要返回記錄集的開始位置,必須先關(guān)閉光標(biāo),再打開光標(biāo),它對(duì)與只需要瀏覽一次的應(yīng)用非常有用,而且效率很高。 (2) 可滾動(dòng)光標(biāo) 可滾動(dòng)光標(biāo)常用于基于圖形用戶界面的程序,用戶通過屏幕向前或向后滾動(dòng),瀏覽記錄集中的數(shù)據(jù)。 (3) 塊光標(biāo) 所謂塊光標(biāo),可以理解為執(zhí)行多行的光標(biāo),他所指向的行稱為行集。對(duì)于網(wǎng)絡(luò)環(huán)境下的應(yīng)用,使用塊光標(biāo)可以在一定程度上減輕網(wǎng)絡(luò)負(fù)載。 要使用塊光標(biāo),應(yīng)完成以下工作: ² ² 設(shè)定行集大小 &

54、#178;² 綁定行集緩沖區(qū) ² ² 設(shè)定語句句柄屬性 ² ² 取行行集結(jié)果 塊光標(biāo)返回多行記錄,應(yīng)用程序必須把這多行的數(shù)據(jù)綁定到某些數(shù)據(jù)組中,這些數(shù)據(jù)組稱為行集緩沖區(qū)。綁定方式有兩種,列方式和行方式。 (4) ODBC光標(biāo)庫 有些應(yīng)用程序不支持可滾動(dòng)光標(biāo)和塊光標(biāo),ODBC SDK提供了一個(gè)光標(biāo)庫(ODBCCR32.DLL),在應(yīng)用程序中可通過設(shè)置連接屬性(SQL_STTR_ODBC_CURSORS)激活光標(biāo)庫。 先用函數(shù)SQLExecDirect執(zhí)行SQL語句,接著用函數(shù)SQLBindCol綁定列,然后用函數(shù)SQLFetch遍歷記錄,獲取記錄

55、的參考代碼如下: #define NAME_LEN 50 #define PHONE_LEN 10 SQLCHAR szNameNAME_LEN, szPhonePHONE_LEN; SQLINTEGER sCustID, cbName, cbCustID, cbPhone; SQLHSTMT hstmt; SQLRETURN retcode; /執(zhí)行SQL語句retcode = SQLExecDirect(hstmt, “SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY 2,1,3”, SQL_NTS); if(retcode != SQL

56、_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) /執(zhí)行成功 /綁定1,2,3列 SQLBindCol(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);SQLBindCol(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName); SQLBindCol(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN, &cbPhone); /遍歷記錄集,輸出結(jié)果 while(TRUE) retcode = SQLFetc

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論