3使用ODBCAPI訪問數(shù)據(jù)庫_第1頁
3使用ODBCAPI訪問數(shù)據(jù)庫_第2頁
3使用ODBCAPI訪問數(shù)據(jù)庫_第3頁
3使用ODBCAPI訪問數(shù)據(jù)庫_第4頁
3使用ODBCAPI訪問數(shù)據(jù)庫_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quá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 和 SQLGetDiagField 處理錯誤使用函數(shù) SQLFetch 移動數(shù)據(jù)庫記錄指針使用 ODBC API 進行事務(wù)處理使用函數(shù) SQLDisconnect 斷開數(shù)據(jù)源的連接目錄ODBC API

2、 基礎(chǔ) 3ODBC AP句柄3ODBC數(shù)據(jù)類型5ODBC診斷 6使用ODBC API變成建立應(yīng)用程序 8ODBC AP編程模型概述 8連接數(shù)據(jù)庫 11準備并執(zhí)行 SQL語句 16獲取記錄集 18記錄的添加、刪除和更新 20錯誤處理 23事務(wù)處理 23斷開數(shù)據(jù)源連接并釋放環(huán)境句柄 25ODBC API 基礎(chǔ)ODBC API 句柄ODBC API 實現(xiàn)數(shù)據(jù)庫操作的手段是句柄。在 ODBC 中,使用不同的句柄(HANDLE 來標志環(huán)境(environment)、連接(Connection)、語句(statement)、 描述符(description)等。句柄是一個應(yīng)用程序變量,系統(tǒng)用它來存儲關(guān)于應(yīng)

3、用 程序的上下文信息和應(yīng)用程序所用到的一些對象。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)境上分配的連接句柄、 每個環(huán)境屬性的當(dāng) 前設(shè)置。在實現(xiàn)ODBC的一段代碼(Driver Manager或者驅(qū)動程序)中,環(huán)境句柄標 識包含這個信息的結(jié)構(gòu)。環(huán)境句柄在ODBC應(yīng)用程序中不經(jīng)常用。他們經(jīng)常用來 調(diào)用 SQLDataSources 和 SQLDrivers 又是用來調(diào)用函數(shù) SQLAIIocHa ndle SQLEndTran SQLFreeHandle SQLGetDiagField和 SQLGetDiagReg環(huán)

4、境句柄ODBC中整個上下文的句柄,使用ODBC的每個程序從創(chuàng)建環(huán)境句 柄開始、以釋放環(huán)境句柄結(jié)束。所有其他的句柄都由環(huán)境句柄的上下文來管理。 環(huán)境句柄在每個應(yīng)用程序中只能創(chuàng)建一個。2、連接句柄一個連接包含一個驅(qū)動程序和一個數(shù)據(jù)源。 連接句柄標識每個連接。 連接句 柄定義使用哪個驅(qū)動程序和該驅(qū)動程序使用的數(shù)據(jù)源。 在執(zhí)行一段 ODBC(Driver Man ager或者驅(qū)動程序)的代碼中,連接句柄標志一個包含連接信息的結(jié)構(gòu)。比 如:連接狀態(tài)、當(dāng)前連接層診斷、語句句柄和當(dāng)前連接上分配的描述符、每個連 接屬性的當(dāng)前設(shè)置。如果驅(qū)動程序支持多個同時連接,ODBC并不阻止多個同時的連接。因此, 在特定的O

5、DBC環(huán)境中,多個連接句柄可能指向不同的驅(qū)動程序和數(shù)據(jù)源、相同 的驅(qū)動程序和不同的數(shù)據(jù)源甚至是與相同的驅(qū)動程序和數(shù)據(jù)源的多個連接。 一些 驅(qū) 動 程 序 限 制 他 們 支 持 的 活 動 連 接 數(shù) 目 , SQLGetInfo 中 的 SQL_MAX_DRIVER_CONNECTIO選SS可指定一個特定的驅(qū)動程序支持多少個活 動連接。與數(shù)據(jù)源進行連接(SQLConnect SQLDriverConnect或 SQLBrowseConnec)、 從數(shù)據(jù)源上斷開(SQLDisconnec)獲取驅(qū)動程序及數(shù)據(jù)源信息(SQLGetlnfo、 檢索診斷(SQLGetDiagFielc和 SQLGet

6、DiagRe)和執(zhí)行事務(wù)(SQLEndTra"時, 都需要使用連接句柄。當(dāng)設(shè)置和獲取連接屬性( SQLSetConnectAttr 及獲取 SQL 語句內(nèi)部格式( SQLNativeSql 時,也使用它們。在應(yīng)用程序中, 可在任何適當(dāng)?shù)臅r候連接或脫離數(shù)據(jù)源, 但不要輕易的建立 或脫離連接。3、語句句柄一個語句不只是一個SQL語句,它包含所有與那個SQL語句相關(guān)的信息,女口 任何由語句和語句執(zhí)行中使用的參數(shù)建立的結(jié)果集。 一個語句甚至不需要應(yīng)用程 序的SQL語句。例如,當(dāng)在一個語句上執(zhí)行如 SQLTable這樣的編目函數(shù)時,它 執(zhí)行返回表名列表的預(yù)定義SQL語句。每個語句由語句句柄標識

7、。 一個語句與單個的連接相關(guān), 并且在那個連接上 可能有多個語句。一些驅(qū)動程序限制它們支持活動語句的數(shù)目,在 SQLGetInfo 中SQL_MAX_CONCURRENT_ACTIVIT選項指定一個驅(qū)動程序在單個的連接上支 持多少個活動的語句。 如果它的結(jié)果是未確定的, 那么語句被定義成 “活動的”, 其結(jié)果既不是結(jié)果集,也不是受INSERT UPDATE或DELETE語句影響的行數(shù), 或者用多個調(diào)用把數(shù)據(jù)發(fā)送到 SQLPutData。在實現(xiàn) ODBC(Driver Manager 或驅(qū)動程序、的一段代碼中,語句句柄標識 一個包含語句信息的結(jié)構(gòu),如:語句狀態(tài)、當(dāng)前語句層診斷、應(yīng)用程序變量綁定

8、到語句參數(shù)和結(jié)果集列的地址、每個語句屬性的當(dāng)前設(shè)置。語句句柄在大多數(shù) ODBC函數(shù)中使用,它們用于函數(shù)綁定參數(shù)及結(jié)果集列(SQLBindParameter和 SQLBindCc)、準備執(zhí)行語句(SQLPrepare SQLExecute 和 SQLExecDirec)、檢索元數(shù)據(jù)(SQLColAttribute 和 SQLDescribeCc、I、取結(jié)果(SQLFetch和檢索診斷(SQLGetDiagFiel(和SQLGetDiagRe) 它們還在編目函 數(shù)(SQLColum ns SQLTables等)和其他一些函數(shù)中使用。語句句柄使用 SQLAllocHandle分配,使用 SQLFre

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

10、 度、和可控性。四種描述符(一種承擔(dān)一個角色)在分配語句時自動分配,且總是與那條語 句相關(guān)。稱為自動分配描述符。應(yīng)用程序還可用 SQLAIIocHa ndle分配描述符,稱 為顯示分配描述符。它們根據(jù)連接進行分配,并且可以與那個連接上的一條或多 條語句關(guān)聯(lián),來履行那些語句上的 APD或ARD的職責(zé)。應(yīng)用程序可完成ODBC中的大多數(shù)操作,而不明確使用描述符。然而,描述 符可以為有些操作提供方便的快捷方式。例如,假設(shè)一個應(yīng)用程序想從兩套不同 的緩沖區(qū)插入數(shù)據(jù)。要用第一套緩沖區(qū),它會反復(fù)調(diào)用SQLBi ndParameter來把它們綁定至INSERT語句的參數(shù)中,然后再執(zhí)行該語句。要使用第二套緩沖區(qū)

11、, 它就會重復(fù)這個過程。另一種方法就是在一個描述符中建立起對第一套緩沖區(qū)的 綁定,在另一個描述符中建立對第二套緩沖區(qū)的綁定。要在兩套綁定集間切換, 只需調(diào)用SQLSetStmtAtt,并把正確的描述符作為 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ù)類型。 每個數(shù)據(jù)源都定義了它自己的 SQL數(shù)據(jù)類型。ODBC定義類型標識符并且描述可能映射為每一種類型標識符的 SQL數(shù)據(jù)類型的一種特征。在基本數(shù)據(jù)源中,每一種數(shù)據(jù)類型如何映射為OD

12、BC的SQL類型標識符是由驅(qū)動程序制定的。ODBC中定義的常用SQL數(shù)據(jù)類型如表所示,此處列出了部分常用的類型, 詳細資料參見ODBC的技術(shù)手冊:SQL類型標識SQL類型舉例SQL CHARCHAR( n)SQL VACHARVACHAR (n)SQL LONGVACHARLONG VACHARSQL WCHARWCHAR (n)2、C數(shù)據(jù)類型ODBCS義了由應(yīng)用程序變量及其相應(yīng)的數(shù)據(jù)標識符所使用的C數(shù)據(jù)類型。在其他的事情中,它們也用于綁定至結(jié)果集列和語句參數(shù)的緩沖區(qū)。ODBC還定義了一個從每個數(shù)據(jù)類型到一個 C數(shù)據(jù)類型的默認映射。要使用默認映射,應(yīng)用 程序可指定SQL_C_DEFAU類型標識

13、符。但是,出于互操作性的原因,不主張使 用這個標識符。在ODBC 1.x版本中定義的所有整數(shù)C數(shù)據(jù)類型都是帶符號的。 在ODBC 2.0中添加了不帶符號的C數(shù)據(jù)類型及其相應(yīng)的數(shù)據(jù)標識符。ODBC中定義的常用C數(shù)據(jù)類型如表所示,此處列出了部分常用的類型,詳 細資料參見ODBC的技術(shù)手冊:C類型標識ODBC C類型定義C類型SQL C CHARSQLCHARUn sig ned char *SQL C SSHORTSQLSMALLINTShort intSQL C USHORTjSQLUSMALLINTUn sig ned short intSQL C SLONGjSQLINTEGERLong i

14、ntODBC診斷為了在程序開發(fā)過程中調(diào)試程序,發(fā)現(xiàn)程序錯誤,ODBC API通過兩種方式返回有關(guān)ODBC AP函數(shù)執(zhí)行的信息:返回碼和診斷記錄。返回碼返回函數(shù)執(zhí)行 的返回值,說明函數(shù)執(zhí)行成功與否;診斷記錄說明函數(shù)執(zhí)行的詳細信息。1、返回碼(Return Code每一個ODBC AP函數(shù)都返回一個代碼一一返回碼,指示函數(shù)執(zhí)行的成功與 否。如果函數(shù)調(diào)用成功,返回碼為 SQL_SUCCES指示可通過診斷記錄獲取相關(guān) 操作的詳細信息)或SQL_SUCCESS_WITHN指示應(yīng)用程序執(zhí)行結(jié)果帶有警告 信息,可通過診斷記錄獲取詳細的信息)。如果函數(shù)調(diào)用失敗,返回碼為SQL_ERROR下面一段代碼根據(jù)函數(shù)

15、SQLFetch()執(zhí)行的返回碼,判斷函數(shù)執(zhí)行的成功與 否,從而據(jù)此進行相應(yīng)的處理:SQLRETURN rtcode;SQLHSTMT hstmt;While(rtcode = SQLFetch(hstmt) != SQL_NO_DATA) If(rtcode = SQL_SUCCESS_WITH_INFO)/ 顯示警告信息else/ 顯示出錯信息break;/ 函數(shù)調(diào)用成功如果程序執(zhí)行錯誤,返回碼為 sql_invalid_handj_E?序無法執(zhí)行,而其 他的返回碼都帶有程序執(zhí)行信息。2、診斷記錄每個ODBC AP函數(shù)都能產(chǎn)生一系列的反應(yīng)操作信息的診斷記錄,這些診斷 記錄都放在相關(guān)聯(lián)的OD

16、B(句柄中,直到下一個使用同一個句柄的函數(shù)調(diào)用,該 診斷記錄一直存在。診斷記錄的大小沒有限制。診斷記錄有兩種:頭記錄(Head Record)和狀態(tài)記錄(Status Record )。 頭記錄是第一版權(quán)記錄(Record。),后面的記錄為狀態(tài)記錄。診斷記錄有許多的 域組成,這些域在頭記錄和狀態(tài)記錄中是不同的。可以用 SQLGetDiagField 函數(shù)獲取診斷記錄中的特定的域, 另外,可以使用 SQLGetDiagRec()函數(shù)獲取診斷記錄中一些常用的域,女口 SQLSTATE原始錯誤號 等。(1) 頭記錄頭記錄的各個域中包含了一個函數(shù)執(zhí)行的通用信息, 無論函數(shù)執(zhí)行成功與否, 只要不返回sq

17、l_invalid_handlE?E會生成頭記錄。(2) 狀態(tài)記錄狀態(tài)記錄中的每個域包含了驅(qū)動管理器、ODBC驅(qū)動程序或數(shù)據(jù)源返回的特定的錯誤或警告信息,包括SQLSTATE原始錯誤碼、診斷信息、列號和行號等。 只有函數(shù)執(zhí)行返回 SQL_ERRO、 RSQL_STiLL_EXEUTiN、GSQL_SUCCESS_WiTH_i、NFO SQL_NEED_DAUASQL_NO_DATA,才會生成診斷記錄。(3) 使用 SQLGetDiagRec和 SQLGetDiagField應(yīng)用程序可以調(diào)用SQLGetDiagRec和SQLGetDiagField函數(shù)獲取診斷信息。 對于給定的句柄, 這兩個函數(shù)

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

19、 I,MsgLen;SQLRETURN rc1, rc2;SQLHSTME Hstmt;/Prompt the user for an SQL statementGetSQLStmt(SQLStmt);/執(zhí)行SQL語句返回錯誤結(jié)果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, &NativeE

20、rror, Msg, sizeof(Msg), &MsgLen) != SQL_NO_DATA)DisplayError(SqlState, NativeError, Msg, MsgLen);i+;if(rc1 = SQL_SUCCESS) | (rc1 = SQL_SUCCESS_WITH_INFO)/如果必要就處理結(jié)果使用ODBC AP變成建立應(yīng)用程序ODBC API 編程模型概述使用ODB0PI編寫的程序運行時相對要簡潔、高效。一般,編寫 ODBC?序 主要有以下幾個步驟:為ODBC分配環(huán)境句柄分配一個連接句柄用SQL命令分配一個語句句柄執(zhí)行該命令返回結(jié)果集 斷開同數(shù)據(jù)源的連接

21、 釋放ODBC環(huán)境為了更清楚的闡述ODBC AP的調(diào)用步驟以及涉及到的重要函數(shù),總結(jié)了一 個表來說明ODBC AP應(yīng)用的結(jié)構(gòu):ODBC初始化函數(shù)使用ODBC API檢索數(shù)據(jù)執(zhí)行SQL語句使用結(jié)果集釋放空間SQLAIIocHa ndle(ENV)SQLSetE nvAttr SQLAIIocHa ndle(DBC)SQLCo nn ectSQLSetCo nn ectAttrSQLGetI nfoSQLAllocHa ndle(STMT)SQLSetStmtAttrSQLExecDirectOR SQLPrepareSQLExecute所有ODBCS用程序都必須遵循上圖的通用 ODBC AP調(diào)用

22、注冊數(shù)據(jù)源(Access數(shù)據(jù)庫employers.mdb,其中只有一張表emp包含三 個字段:職工號 數(shù)字,關(guān)鍵字 、職工名稱 文本、工作 文本)/添加ODBC數(shù)據(jù)源void CDemo1App:SetODBCSource()CString strAccessPath = m_strExePath +“employers.mdb ”;int iLen = strAccessPath.GetLength();char cpConfigMAX_PATH;/構(gòu)造注冊字符串strcpy(cpConfig, “DSN = daliu0”);strcpy(cpConfig + 10, “DBC=”);st

23、rcpy(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 ”);/注冊數(shù)據(jù)源if(!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN,“Microsoft Access Dri

24、ver(*.mdb)0 ”, cpConfig)/AfxMessageBox( “add odbc source failed! ”);連接數(shù)據(jù)庫連接數(shù)據(jù)庫包括初始化環(huán)境句柄、 初始化連接句柄以及連接數(shù)據(jù)源等幾個步 驟。1、 初始化環(huán)境句柄(1) 分配環(huán)境句柄對于任何ODBCs用程序來說,第一步的工作是裝在驅(qū)動程序管理器,然后 初始化ODB(環(huán)境,分配句柄首先聲明一個SQLHEN類型的變量,然后調(diào)用 SQLAIIocHandle,向其中傳 遞分配的SQLHEN類型的變量地址和SQL_HANDLE_E選項,代碼如下: / 分配環(huán)境句柄m_retcode = SQLAllocHandle(SQL_

25、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ū)動程序分配一個結(jié)構(gòu), 該結(jié)構(gòu)中存放環(huán)境變量, 然后 返回對應(yīng)于該環(huán)境的環(huán)境句柄。一個應(yīng)用程序?qū)?yīng)于一個環(huán)境, 但是同一個環(huán)境可以用于不同數(shù)據(jù)源的連接, 可以使用多個線程,應(yīng)用程序完成數(shù)據(jù)訪問任務(wù),

26、應(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)境屬性, 注冊O(shè)DBC勺版本號,說明應(yīng)用程序所遵從的標準是ODBC 2.x還是ODBC 3.x,相關(guān)代碼如下所示。 使用不同的版本, 相同的參數(shù)作用會不相同, 具體的說明參 見 MSDN/*設(shè)置ODBC版本的環(huán)境屬性*/m_retcode = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if(m_retcode != SQL_SUCC

27、ESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV,設(shè)置 ODBC版本號時失敗”;return FALSE; 其中m_henv是環(huán)境句柄,m_retcode是返回碼,ReportError是一個處理錯 誤的函數(shù)。2、 初始化連接句柄(1) 分配連接句柄分配環(huán)境句柄之后,在建立至數(shù)據(jù)源的連接之前,必須分配一個連接句柄, 每一個到數(shù)據(jù)源的連接對應(yīng)于一個連接句柄。首先,程序定義一個 SQLHDB(類型的變量,用于存放連接句柄,然后調(diào)用 SQLAllocHandle 函數(shù)分配句柄

28、。/ 分配連接句柄 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_retcode是返回 碼(2) 設(shè)置連接屬性 連接屬性表示了一個連接的特性,如登錄等待時間、使用的光標庫等。 所有的連

29、接屬性都有默認值, 也可以通過調(diào)用函數(shù) SQLSetConnectAttr() 設(shè)置,調(diào)用函數(shù) SQLGetConnectAttr() 可獲取這些連接屬性的當(dāng)前設(shè)置值,這兩個 函數(shù)定義如下:SQLSetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr, SQLINTRGER StringLength);SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr,S

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

31、e, / 數(shù)據(jù)源名稱SQLSMALLINT NameLength1, / 數(shù)據(jù)源名稱長度SQLCHAR *UserName, / 用戶 ID/ 用戶 ID 長度/ 用戶口令/ 用戶口令長度SQLSMALLINT NameLength2,SQLCHAR *Authentication,SQLSMALLINT NameLength3 );/ 連接數(shù)據(jù)源 m_retcode = SQLConnect(m_hdbc, (SQLCHAR *)cpServerName, SQL_NTS,(SQLCHAR *)cpUserName, SQL_NTS,(SQLCHAR *)cpPassword, SQL_NT

32、S); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_hdbc, SQL_HANDLE_DBC,連接數(shù)據(jù)庫失??!”;return FALSE;(2) SQLDriverConnect 該函數(shù)用一個連接字符串建立至數(shù)據(jù)源的連接,他可以提供比 SQLConnect 函數(shù)的 3 個參數(shù)更多的信息, 可以讓用戶輸入必要的連接信息, 使用系統(tǒng)中還沒 有定義的數(shù)據(jù)源。如果連接建立, 該函數(shù)會返回完整的連接字符串, 應(yīng)用程序可以使用連接字 符串建立額外的連接,其定義如下:S

33、QLRETURN SQLDriverConnect( SQLHDBC ConnectionHandle; SQLHWND WindowHandle; SQLCHAR *InConnectionString; SQLSMALLINT StringLength1, SQLCHAR *OutConnectionString; SQLSMALLINT BufferLength; SQLSMALLINT *StringLength2Ptr;/ 連接句柄/ 窗口句柄,程序可以用父窗口的句柄或用/ 一個指向連接字符串的指針/ 連接字符串長度/ 一個指向連接字符串的指針/ 存放連接字符串的緩沖區(qū)的長度/ 返回

34、的連接字符串中的字符數(shù)NULL指針SQLUSMALLINT DriverCompletion / 額外的連接信息,可能的取值:SQL_DRIVER_PROMP、T SQL_DRIVER_COMPLET、ESQL_DRIVER_COMPLETE_REQUIR、EDSQL_DRIVER_NOPROMPT);(3) SQLBrowseConnect函數(shù)SQLBrowseConnec支持以一種迭代的方式獲取到數(shù)據(jù)源的連接,直到 最后建立連接。它基于客戶機 / 服務(wù)器體系結(jié)構(gòu),因此本地數(shù)據(jù)庫 (如 Microsoft Access) 不支持該函數(shù)。一般,只提供部分連接信息, 如果足以建立到數(shù)據(jù)源的連接,

35、 則成功建立連 接,否則返回SQL_NEED_DAT并在OutConnectionString 參數(shù)中返回所需要的信息。其定義如下:SQLRETURN SQLBrowseConnect( SQLHDBC ConnectionHandle, SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2Ptr/ 連接句柄/ 指向輸入字符串的指針/ 輸入字符串的指針長度/ 指向輸出字符串

36、的指針/ 存放輸出字符串的緩沖區(qū)的長度/ 實際返回的字符串的長度);連接數(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_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO)

37、) AfxMessageBox(分配環(huán)境句柄失敗!”;return FALSE;/*Set the ODBC version environment attribute*/m_retcode = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION(v,oid *)SQL_OV_ODBC3, 0);if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV, 設(shè)置 odbc 版本號時失敗! ”);

38、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ù)庫 */m_retcode = SQLConnect(m_hdbc, (SQLCHAR *)cpServerName, SQL_N

39、TS,(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;return TRUE;準備并執(zhí)行 SQL 語句1、構(gòu)造SQL語句可以通過3種方式構(gòu)造SQL語句:在程序開發(fā)階段確定:具有易于實現(xiàn)且可在程序編碼時進行測試的優(yōu)點 在運行時確定:提供了極大靈活

40、性,但給程序帶來了困難,卻需要更多的處 理時間由用戶輸入SQL語句:極大的增強了程序的功能,但是程序必須提供有好的 程序界面,且對用戶輸入的語句執(zhí)行一定程序的語法檢查,能夠報告用戶錯 誤。2、執(zhí)行SQL語句(1) 分配語句句柄語句句柄為ODBC區(qū)動程序管理器提供數(shù)據(jù)結(jié)構(gòu),并跟蹤SQL語句的執(zhí)行機器返回的結(jié)果,語句句柄是通過調(diào)用 SQLAllocHandle 函數(shù)分配的。下面的代碼 聲明了一個存放語句句柄的變量 m_hstmt,在函數(shù)中提供該變量的地址指針、所 使用的連接句柄m_hdbc以及選項SQL_HANDLE_STMT m_retcode = SQLAllocHandle(SQL_HAND

41、LE_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ù) SQLGetStmrrAttr() 和 SQLSetStmrrAttr() 用來獲取和設(shè)置一個語句句 柄的選項,使用方式同前面的 SQLGetConnectAttr() 和 SQLSetConnectAttr() 函 數(shù)相同。當(dāng)一個語句句柄使用完成后,調(diào)

42、用函數(shù)SQLFreeHa ndle()釋放句柄。(2) SQLExecDirect()SQLExecDirect()函數(shù)直接執(zhí)行SQL語句,對于只執(zhí)行一次的SQL語句來說, 該函數(shù)是執(zhí)行最快的方法,其定義如下:SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, / 語句句柄SQLCHAR *StatementText,/ 要執(zhí)行的 SQL語句SQLINTEGER TextLength/SQL 語句的長度);Demol中使用該函數(shù)執(zhí)行SQL語句的代碼:m_retcode = SQLExecDirect(m_hstmt, (unsigned char

43、 *)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_hstmt = NULL;return FALSE; SQLPrepare和 SQLExecute()對于需要多次執(zhí)行的SQL語句來說,除了使用SQLExecDirect函數(shù)之外,也 可以在執(zhí)行SQL語句之前,先調(diào)用函數(shù) SQLPr

44、epare()準備SQL語句的執(zhí)行。對 于使用參數(shù)的語句,這可大大提高程序的執(zhí)行速度。而函數(shù) SQLExecute()用來 執(zhí)行一個準備好的語句, 當(dāng)語句中有參數(shù)時, 用當(dāng)前綁定的參數(shù)變量的值。 其定 義如下:SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, / 語句句柄SQLCHAR *StatementText,/ 要執(zhí)行的 SQL語句SQLINTEGER TextLength/SQL 語句的長度);SQLRETURN SQLExecute(SQLHSTMT StatementHandle); /語句句柄(4) 使用參數(shù)使用參數(shù)可以使一條 SQL

45、語句多次執(zhí)行,得到不同的結(jié)果,如下面的一條 SQL語句:INSERT INTO EMP職員號,職工名稱,工作)VALUES(?,?,?)該語句將向表emp中加入一條記錄,通過參數(shù)替換(將句中問號出現(xiàn)的地方 以相應(yīng)的參數(shù)值替換) ,可以在程序運行的時候動態(tài)的添加多條記錄。SQL語句執(zhí)行時,參數(shù)標識符(“? ”)綁定程序中的變量,通過參數(shù)就可以 在程序執(zhí)行時動態(tài)的將值傳入SQL語句。函數(shù)SQLBindParameter()負責(zé)為參數(shù)定義變量,將一段 SQL語句中的一個SQLRETURN SQLBindParameter( SQLHSTMT StatementHandle, SQLUSMALLINT

46、 ParameterNumber,SQLSMALLINT InputOutputType,參數(shù)標識符 (“?”)綁定在一起,實現(xiàn)參數(shù)值的傳遞,其定義如下:/ 語句句柄/綁定的參數(shù)在SQL語句中的序號,在SQL中,所有參數(shù)從左到右依次編號(從1開始)。SQL語句執(zhí)行之前,應(yīng)該為每個參數(shù)調(diào)用函數(shù)SQLBindParameter 綁定到某個程序變量。/ 參數(shù)類型,可為 SQL_PARA_INPU、T SQL_PARAM_INPUT_OUTPU、TSQLSMALLINT ValueType,SQLSMALLINT ParameterType,SQLUINTEGER ColumnSize,SQLSMAL

47、LINT DecimalDigits, SQLPOINTER ParameterValuePtr,SQL_PARAM_OUTPUT/ 參數(shù)的 C 數(shù)據(jù)類型/參數(shù)的SQL數(shù)據(jù)類型/參數(shù)的大小/ 參數(shù)的精度/指向程序中存放參數(shù)值的緩沖區(qū)的指針SQLINTEGER BufferLength,/ 程序中存放參數(shù)值的緩沖區(qū)的字節(jié)數(shù)SQLINTEGER *StrLen_or_IndPtr / 指向存放參數(shù) ParameterValuePtr 的緩沖區(qū)指針 );獲取記錄集查詢記錄集是數(shù)據(jù)源上滿足一定條件的數(shù)據(jù)記錄的集合, 在概念上, 可以看 成是一個臨時存放返回結(jié)果的表。 記錄集可以是空。 在用 SQLEx

48、ecDirect 等函數(shù) 執(zhí)行SQL語句后,就可以從數(shù)據(jù)源中取回記錄集。1、 綁定列從數(shù)據(jù)源取回的數(shù)據(jù)存放在應(yīng)用程序定義的變量中, 因此,必須首先分配與 記錄集中字段相對應(yīng)的變量,然后通過函數(shù) SQLB in dCol將記錄字段同程序變量 綁定在一起。對于長記錄字段,可以通過調(diào)用函數(shù)SQLGetData()直接取回數(shù)據(jù)。綁定字段可以根據(jù)自己的需要全部綁定,也可以綁定其中的某幾個字段。記錄集中的字段可以在任何時候綁定, 但是,新的綁定只有當(dāng)下一次從數(shù)據(jù)源中取數(shù)據(jù)時執(zhí)行的操作才有效,而不會對已經(jīng)取回的數(shù)據(jù)產(chǎn)生影響。通過調(diào)用函數(shù)SQLBindCol將其變量地址賦值為NULL可以結(jié)束對一個記錄 字段的

49、綁定;通過調(diào)用函數(shù)SQLFreeStm,將其中的選項設(shè)為SQL_UNBIND或者 是直接釋放句柄,都會結(jié)束所有記錄字段的綁定。函數(shù)SQLBindCol的定義如下:SQLRETURN SQLBindCol(SQLHSTMT StatementHandle,SQLUSMALLINT ColumnNumber,SQLSMALLINT TargetType,SQLPOINTER TargetValuePtr,SQLINTEGER BufferLength,SQLINTEGER *StrLen_or_IndPtr );2、 SQLFetch()/ 語句句柄/標識要綁定的列號。 數(shù)據(jù)列號從 0開始升序排列

50、, 其中第 0 列用作書簽,則列號從 1 開始/ 數(shù)據(jù)類型/ 綁定到數(shù)據(jù)字段的緩沖區(qū)的地址/ 緩沖區(qū)長度/指向綁定數(shù)據(jù)列使用的長度的指針函數(shù)SQLFetch用于將記錄集中的下一行變?yōu)楫?dāng)前行,并把所有捆綁過的數(shù) 據(jù)字段的數(shù)據(jù)拷貝到相應(yīng)的緩沖區(qū),其定義如下:SQLRETURN SQLFetch(SQLHSTMT StatementHandle); /StatementHandle :語句句柄3、光標應(yīng)用程序獲取數(shù)據(jù)是通過光標(Cursor )來實現(xiàn)的,在ODBC中,主要有3種類型的光標:(1) 單向光標單向光標只能向前移動, 要返回記錄集的開始位置, 必須先關(guān)閉光標, 再打 開光標,它對與只需要瀏

51、覽一次的應(yīng)用非常有用,而且效率很高。(2) 可滾動光標可滾動光標常用于基于圖形用戶界面的程序, 用戶通過屏幕向前或向后滾動, 瀏覽記錄集中的數(shù)據(jù)。(3) 塊光標所謂塊光標, 可以理解為執(zhí)行多行的光標, 他所指向的行稱為行集。 對于網(wǎng) 絡(luò)環(huán)境下的應(yīng)用,使用塊光標可以在一定程度上減輕網(wǎng)絡(luò)負載。要使用塊光標,應(yīng)完成以下工作: 設(shè)定行集大小 綁定行集緩沖區(qū) 設(shè)定語句句柄屬性 取行行集結(jié)果塊光標返回多行記錄,應(yīng)用程序必須把這多行的數(shù)據(jù)綁定到某些數(shù)據(jù)組中, 這些數(shù)據(jù)組稱為行集緩沖區(qū)。綁定方式有兩種,列方式和行方式。ODBC光標庫有些應(yīng)用程序不支持可滾動光標和塊光標,ODBC SDK提供了一個光標庫(ODB

52、CCR32.DLL在應(yīng)用程序中可通過設(shè)置連接屬性 (SQL_STTR_ODBC_CURSORS激活光標庫。先用函數(shù)SQLExecDirect執(zhí)行SQL語句,接著用函數(shù)SQLBindCol綁定列,然后用函數(shù)SQLFetch遍歷記錄,獲取記錄的參考代碼如下:#define NAME_LEN 50#define PHONE_LEN 10SQLCHAR szNameNAME_LEN, szPhonePHONE_LEN;SQLINTEGER sCustID, cbName, cbCustID, cbPhone;SQLHSTMT hstmt;SQLRETURN retcode;/執(zhí)行SQL語句 retco

53、de = SQLExecDirect(hstmt,“SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY”,2S,1Q,3L_NTS); if(retcode != SQL_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,

54、&cbName);SQLBindCol(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN, &cbPhone);/ 遍歷記錄集,輸出結(jié)果while(TRUE)retcode = SQLFetch(hstmt);if(retcode = SQL_ERROR | retcode = SQL_SUCCESS_WITH_INFO)/ 出錯,輸出錯誤,返回show_error();if(retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO)fprintf(out, “%-*s %-5d %*s”,N

55、AME_LEN-1, szName, sCustID, PHONE_LEN-1,szPhone);elsebreak;記錄的添加、刪除和更新應(yīng)用程序?qū)?shù)據(jù)源的數(shù)據(jù)更新可以通過 3種方式實現(xiàn):通過 SQLExecDirect 函數(shù)使用相應(yīng)的SQL語句在數(shù)據(jù)源上執(zhí)行,調(diào)用SQLSetPos函數(shù)實現(xiàn)記錄集的定 義更新,調(diào)用 SQLBulkOperations 函數(shù)實現(xiàn)數(shù)據(jù)的更新。直接在數(shù)據(jù)源上執(zhí)行SQL語句的方式可以適用于任何的 ODB數(shù)據(jù)源,但是, 對于后兩種更新方式, 有的數(shù)據(jù)源并不支持, 應(yīng)用程序可以調(diào)用函數(shù) SQLGetInfo 確定數(shù)據(jù)源是否支持著兩種方式。1、直接執(zhí)行SQL語句在Demo

56、l中專門有一個函數(shù)負責(zé)執(zhí)行 SQL語句,其代碼如下:BOOL CMyODBC:ExeSqlDirect(const char *cpSqlStmt)SQLHSTMT hstmt;if(this->m_hdbc = NULL)AfxMessageBox(沒有連接數(shù)據(jù)庫,請先連接!”;return FALSE;/ 分配連接句柄m_retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &hStmt); if(m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_hdbc, SQL_HANDLE_DBC,“ 分配語句句柄失敗,不能執(zhí)行 ”); return FALSE;II直接執(zhí)行SQL語句m_retcode = SQLExecDirect(hstmt, (unsigned char *)cp

溫馨提示

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

評論

0/150

提交評論