使用ODBC API 連接數(shù)據(jù)庫(共24頁)_第1頁
使用ODBC API 連接數(shù)據(jù)庫(共24頁)_第2頁
使用ODBC API 連接數(shù)據(jù)庫(共24頁)_第3頁
使用ODBC API 連接數(shù)據(jù)庫(共24頁)_第4頁
使用ODBC API 連接數(shù)據(jù)庫(共24頁)_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、主要(zhyo)內(nèi)容: ODBC API的體系結(jié)構(gòu) 使用(shyng)ODBC API開發(fā)數(shù)據(jù)庫應(yīng)用程序的一般步驟 使用(shyng)函數(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 進(jìn)行事務(wù)處理 使用函數(shù)SQLDisconnect斷開數(shù)據(jù)源的

2、連接 目錄(ml)TOC o 1-3 h u HYPERLINK l _Toc30793 ODBC API 基礎(chǔ)(jch) PAGEREF _Toc30793 3 HYPERLINK l _Toc22242 ODBC API句柄 PAGEREF _Toc22242 3 HYPERLINK l _Toc5102 ODBC數(shù)據(jù)類型 PAGEREF _Toc5102 5 HYPERLINK l _Toc22898 ODBC診斷(zhndun) PAGEREF _Toc22898 5 HYPERLINK l _Toc15710 使用ODBCAPI變成建立應(yīng)用程序 PAGEREF _Toc15710 7

3、 HYPERLINK l _Toc13536 ODBCAPI編程模型概述 PAGEREF _Toc13536 7 HYPERLINK l _Toc25206 連接數(shù)據(jù)庫 PAGEREF _Toc25206 10 HYPERLINK l _Toc25488 準(zhǔn)備并執(zhí)行SQL語句 PAGEREF _Toc25488 14 HYPERLINK l _Toc12317 獲取記錄集 PAGEREF _Toc12317 16 HYPERLINK l _Toc21145 記錄的添加、刪除和更新 PAGEREF _Toc21145 18 HYPERLINK l _Toc11183 錯誤處理 PAGEREF _

4、Toc11183 20 HYPERLINK l _Toc5116 事務(wù)處理 PAGEREF _Toc5116 21 HYPERLINK l _Toc8412 斷開數(shù)據(jù)源連接并釋放環(huán)境句柄 PAGEREF _Toc8412 23ODBC API 基礎(chǔ)(jch)ODBC API句柄ODBC API 實現(xiàn)數(shù)據(jù)庫操作的手段是句柄。在ODBC中,使用不同的句柄(HANDLE)來標(biāo)志環(huán)境(environment)、連接(Connection)、語句(statement)、描述符(description)等。句柄是一個應(yīng)用程序變量,系統(tǒng)用它來存儲(cn ch)關(guān)于應(yīng)用程序的上下文信息和應(yīng)用程序所用到的一些對

5、象。 1、 環(huán)境(hunjng)句柄 環(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)境句柄標(biāo)識包含這個信息的結(jié)構(gòu)。環(huán)境句柄在ODBC應(yīng)用程序中不經(jīng)常用。他們經(jīng)常用來調(diào)用SQLDataSources和SQLDrivers,又是用來調(diào)用函數(shù)SQLAllocHandle、SQLEndTran、SQLFreeHandle、SQLGetDiagField和SQLGetDiagReg。 環(huán)境句柄ODBC中整個上下文的句柄,使用ODBC

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

7、同的驅(qū)動程序和不同的數(shù)據(jù)源甚至是與相同的驅(qū)動程序和數(shù)據(jù)源的多個連接。一些驅(qū)動程序限制他們支持的活動連接數(shù)目,SQLGetInfo中的SQL_MAX_DRIVER_CONNECTIONS選項可指定一個特定的驅(qū)動程序支持多少個活動連接。與數(shù)據(jù)源進(jìn)行連接(SQLConnect、SQLDriverConnect或SQLBrowseConnect)、從數(shù)據(jù)源上斷開(SQLDisconnect)、獲取驅(qū)動程序及數(shù)據(jù)源信息(SQLGetInfo)、檢索診斷(SQLGetDiagField和SQLGetDiagRec)和執(zhí)行事務(wù)(SQLEndTran)時,都需要使用連接句柄。當(dāng)設(shè)置和獲取連接屬性(SQLSet

8、ConnectAttr)及獲取SQL語句內(nèi)部格式(SQLNativeSql)時,也使用它們。 在應(yīng)用程序中,可在任何適當(dāng)?shù)臅r候連接或脫離(tul)數(shù)據(jù)源,但不要輕易的建立或脫離連接。 3、 語句(yj)句柄 一個語句不只是一個SQL語句,它包含所有與那個SQL語句相關(guān)的信息,如任何由語句和語句執(zhí)行中使用的參數(shù)建立的結(jié)果集。一個語句甚至(shnzh)不需要應(yīng)用程序的SQL語句。例如,當(dāng)在一個語句上執(zhí)行如SQLTables這樣的編目函數(shù)時,它執(zhí)行返回表名列表的預(yù)定義SQL語句。 每個語句由語句句柄標(biāo)識。一個語句與單個的連接相關(guān),并且在那個連接上可能有多個語句。一些驅(qū)動程序限制它們支持活動語句的數(shù)目

9、,在SQLGetInfo中SQL_MAX_CONCURRENT_ACTIVITIES選項指定一個驅(qū)動程序在單個的連接上支持多少個活動的語句。如果它的結(jié)果是未確定的,那么語句被定義成“活動的”,其結(jié)果既不是結(jié)果集,也不是受INSERT、UPDATE、或DELETE語句影響的行數(shù),或者用多個調(diào)用把數(shù)據(jù)發(fā)送到SQLPutData。 在實現(xiàn)ODBC(Driver Manager或驅(qū)動程序)的一段代碼中,語句句柄標(biāo)識一個包含語句信息的結(jié)構(gòu),如:語句狀態(tài)、當(dāng)前語句層診斷、應(yīng)用程序變量綁定到語句參數(shù)和結(jié)果集列的地址、每個語句屬性的當(dāng)前設(shè)置。 語句句柄在大多數(shù)ODBC函數(shù)中使用,它們用于函數(shù)綁定參數(shù)及結(jié)果集列

10、(SQLBindParameter和SQLBindCol)、準(zhǔn)備執(zhí)行語句(SQLPrepare、SQLExecute和SQLExecDirect)、檢索元數(shù)據(jù)(SQLColAttribute和SQLDescribeCol)、取結(jié)果(SQLFetch)和檢索診斷(SQLGetDiagField和SQLGetDiagRec)。它們還在編目函數(shù)(SQLColumns,SQLTables等)和其他一些函數(shù)中使用。語句句柄使用SQLAllocHandle分配,使用SQLFreeHandle釋放。 4、 描述符句柄 從應(yīng)用程序或驅(qū)動程序來看,描述符就是描述SQL語句的參數(shù)或結(jié)果集列的元數(shù)據(jù)集合。因此,描述

11、符可用來擔(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ù)類型、長 度、和可控性。 四種描述符(一種承擔(dān)一個角色)在分配語句時自動分配,且總是與那條語句相關(guān)。稱為自動分配描述符。應(yīng)用程序還可用S

12、QLAllocHandle分配描述符,稱為顯示分配描述符。它們根據(jù)連接進(jìn)行分配,并且可以與那個連接上的一條或多條語句關(guān)聯(lián),來履行那些語句上的APD或ARD的職責(zé)。 應(yīng)用程序可完成ODBC中的大多數(shù)操作,而不明確使用描述符。然而,描述符可以為有些操作提供方便的快捷方式。例如,假設(shè)一個應(yīng)用程序想從兩套不同的緩沖區(qū)插入數(shù)據(jù)。要用第一套緩沖區(qū),它會反復(fù)調(diào)用SQLBindParameter來把它們綁定至INSERT語句的參數(shù)中,然后再執(zhí)行該語句。要使用第二套緩沖區(qū),它就會重復(fù)這個過程。另一種方法就是在一個描述符中建立起對第一套緩沖區(qū)的綁定,在另一個描述符中建立對第二套緩沖區(qū)的綁定。要在兩套綁定集間切換,

13、只需調(diào)用SQLSetStmtAttr,并把正確(zhngqu)的描述符作為APD與語句聯(lián)系起來即可。 ODBC數(shù)據(jù)類型 ODBC使用(shyng)兩套數(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定義類型標(biāo)識符并且(bngqi)描述可能映射為每一種類型標(biāo)識符的SQL數(shù)據(jù)類型的一種特征。在基本數(shù)據(jù)源中,每一種數(shù)據(jù)類型如何映射為ODBC的SQL類型標(biāo)識符是由驅(qū)動程序制定的。 ODBC中定義的常用SQL數(shù)據(jù)類型如表所示,此處列出了部分

14、常用的類型,詳細(xì)資料參見ODBC的技術(shù)手冊:SQL類型標(biāo)識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)識符所使用的C數(shù)據(jù)類型。在其他的事情中,它們也用于綁定至結(jié)果集列和語句參數(shù)的緩沖區(qū)。ODBC還定義了一個從每個數(shù)據(jù)類型到一個C數(shù)據(jù)類型的默認(rèn)映射。要使用默認(rèn)映射,應(yīng)用程序可指定SQL_C_DEFAULT類型標(biāo)識符。但是,出于互操作性的原因,不主張使用這個標(biāo)識符。在ODBC 1.x版本中定義的所有整數(shù)C數(shù)據(jù)類

15、型都是帶符號的。在ODBC 2.0中添加了不帶符號的C數(shù)據(jù)類型及其相應(yīng)的數(shù)據(jù)標(biāo)識符。 ODBC中定義的常用C數(shù)據(jù)類型如表所示,此處列出了部分常用的類型,詳細(xì)資料參見ODBC的技術(shù)手冊: C類型標(biāo)識ODBC C類型定義C類型SQL_C_CHARSQLCHARUnsigned char *SQL_C_SSHORTSQLSMALLINTShort intSQL_C_USHORTjSQLUSMALLINTUnsigned short intSQL_C_SLONGjSQLINTEGERLong intODBC診斷(zhndun) 為了在程序開發(fā)過程(guchng)中調(diào)試程序,發(fā)現(xiàn)程序錯誤,ODBC AP

16、I 通過兩種方式返回有關(guān)ODBC API函數(shù)執(zhí)行的信息:返回碼和診斷記錄。返回碼返回函數(shù)執(zhí)行的返回值,說明函數(shù)執(zhí)行成功與否;診斷記錄說明函數(shù)執(zhí)行的詳細(xì)信息。 1、 返回(fnhu)碼(Return Code) 每一個ODBC API函數(shù)都返回一個代碼返回碼,指示函數(shù)執(zhí)行的成功與否。如果函數(shù)調(diào)用成功,返回碼為SQL_SUCCESS(指示可通過診斷記錄獲取相關(guān)操作的詳細(xì)信息)或SQL_SUCCESS_WITH_INFO(指示應(yīng)用程序執(zhí)行結(jié)果帶有警告信息,可通過診斷記錄獲取詳細(xì)的信息)。如果函數(shù)調(diào)用失敗,返回碼為SQL_ERROR。 下面一段代碼根據(jù)函數(shù)SQLFetch()執(zhí)行的返回碼,判斷函數(shù)執(zhí)行

17、的成功與否,從而據(jù)此進(jìn)行相應(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_HANDLE,程序無法執(zhí)行,而其他的返回碼都帶有程序執(zhí)行信息。 2、 診斷記錄 每個ODBC API函數(shù)都能產(chǎn)生一系列的反應(yīng)操作信息的診斷記錄,這些診斷記錄都放在相關(guān)聯(lián)的ODBC句柄中,直到下一個使用同一個句

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

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

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

21、c2;SQLHSTMEHstmt;/PrompttheuserforanSQLstatementGetSQLStmt(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,&NativeError,Msg,sizeof(Msg),&MsgLen)!=SQL_NO_DATA)DisplayError

22、(SqlState,NativeError,Msg,MsgLen);i+;if(rc1=SQL_SUCCESS)|(rc1=SQL_SUCCESS_WITH_INFO)/如果(rgu)必要就處理結(jié)果使用(shyng)ODBCAPI變成建立(jinl)應(yīng)用程序ODBCAPI編程模型概述使用ODBC API編寫的程序運行時相對要簡潔、高效。一般,編寫ODBC程序主要有以下幾個步驟: 為ODBC分配環(huán)境句柄分配一個連接句柄 用SQL命令分配一個語句句柄 執(zhí)行該命令返回結(jié)果集 斷開同數(shù)據(jù)源的連接 釋放ODBC環(huán)境 為了更清楚的闡述ODBC API的調(diào)用步驟以及涉及到的重要函數(shù),總結(jié)了一 個表來說明OD

23、BC API應(yīng)用的結(jié)構(gòu): SQLAllocHandle(ENV)SQLSetEnvAttrSQLAllocHandle(DBC)SQLConnectSQLSetConnectAttrSQLGetInfo SQLAllocHandle(STMT)SQLSetStmtAttrODBC初始化函數(shù)SQLExecDirectOR SQLPrepareSQLExecute使用ODBC API 檢索數(shù)據(jù)Select OR Update/Delete/InsertSQLNumResultColsSQLBindCOL SQLFetchSQLGetDataSQLCloseCursor執(zhí)行SQL語句使用結(jié)果集SQL

24、FreeHandle(STMT)SQLDisconnect SQLFreeHandle(DBC)SQLFreeHandle(ENV)釋放空間所有(suyu)ODBC應(yīng)用程序都必須遵循上圖的通用ODBC API調(diào)用 注冊數(shù)據(jù)源(Access數(shù)據(jù)庫employers.mdb,其中只有一張表emp,包含三個字段:職工號、職工名稱、工作) /添加(tin ji)ODBC數(shù)據(jù)源 void CDemo1App:SetODBCSource() CString strAccessPath = m_strExePath + “employers.mdb”; int iLen = strAccessPath.Ge

25、tLength(); char cpConfigMAX_PATH; /構(gòu)造注冊字符串 strcpy(cpConfig,“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 + i

26、Len + m_strExePath.GetLength(), “00 ”); /注冊數(shù)據(jù)源 if(!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, “Microsoft Access Driver(*.mdb)0”, cpConfig) /AfxMessageBox(“add odbc source failed!”); 連接數(shù)據(jù)庫 連接數(shù)據(jù)庫包括初始化環(huán)境句柄、初始化連接句柄以及連接數(shù)據(jù)源等幾個步驟。 1、 初始化環(huán)境句柄 (1) 分配環(huán)境句柄 對于任何ODBC應(yīng)用程序來說,第一步的工作(gngzu)是裝在驅(qū)動程序管理器,然后初始化ODBC環(huán)境,分配

27、句柄 首先聲明一個SQLHENV類型的變量,然后調(diào)用SQLAllocHandle,向其中傳遞分配的SQLHENV類型的變量地址(dzh)和SQL_HANDLE_ENV選項,代碼如下: /分配(fnpi)環(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)境

28、句柄,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ù),應(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)用程序所遵從的標(biāo)準(zhǔn)是ODBC 2.x還是ODBC 3.x,相關(guān)代碼如下所示。使用不同的版本,相同的參數(shù)作用會不相同,具體的說明參見MSDN。 /*設(shè)置ODBC版

29、本的環(huán)境屬性*/ m_retcode=SQLSetEnvAttr(m_henv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0); if(m_retcode != SQL_SUCCESS) & (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)境句

30、柄之后,在建立至數(shù)據(jù)源的連接之前,必須分配一個連接句柄,每一個到數(shù)據(jù)源的連接對應(yīng)于一個連接句柄。 首先,程序定義一個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, “分配(fnpi)連接句柄失?。 ?; re

31、turn FALSE; 其中m_henv是環(huán)境句柄,m_hdbc是要分配(fnpi)的連接句柄,m_retcode是返回碼 (2) 設(shè)置(shzh)連接屬性 連接屬性表示了一個連接的特性,如登錄等待時間、使用的光標(biāo)庫等。 所有的連接屬性都有默認(rèn)值,也可以通過調(diào)用函數(shù)SQLSetConnectAttr()設(shè)置,調(diào)用函數(shù)SQLGetConnectAttr()可獲取這些連接屬性的當(dāng)前設(shè)置值,這兩個函數(shù)定義如下: SQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTR

32、GER StringLength ); SQLRETURN SQLGetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLengthPtr ); 3、 連接數(shù)據(jù)源 完成連接屬性的設(shè)置之后,就可以建立到數(shù)據(jù)源的連接了。對于不同的程序和用戶接口,可以用不同的函數(shù)建立連接:SQLConnect、SQLDriverConnect、SQLBrowseConnect (1) SQLConnect 該函數(shù)提供

33、了最為直接的程序控制方式,只要提供數(shù)據(jù)源名稱、用戶ID和口令,就可以進(jìn)行連接了。其定義如下: SQLRETURN SQLConnect( SQLHDBC ConnectionHandle, /連接句柄 SQLCHAR *ServerName, /數(shù)據(jù)源名稱 SQLSMALLINT NameLength1, /數(shù)據(jù)源名稱長度SQLCHAR *UserName, /用戶ID SQLSMALLINT NameLength2, /用戶ID長度 SQLCHAR *Authentication, /用戶口令 SQLSMALLINT NameLength3 /用戶口令長度 ); /連接數(shù)據(jù)源 m_retco

34、de = 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) ReportError(m_hdbc, SQL_HANDLE_DBC, “連接(linji)數(shù)據(jù)庫失敗!”); return FALSE; (2) SQLDriverConnect 該函數(shù)用一個連接字符串建立至數(shù)據(jù)源的

35、連接,他可以提供比SQLConnect函數(shù)的3個參數(shù)更多的信息,可以讓用戶輸入必要(byo)的連接信息,使用系統(tǒng)中還沒有定義的數(shù)據(jù)源。 如果連接建立,該函數(shù)會返回完整(wnzhng)的連接字符串,應(yīng)用程序可以使用連接字符串建立額外的連接,其定義如下: SQLRETURN SQLDriverConnect( SQLHDBC ConnectionHandle; /連接句柄 SQLHWND WindowHandle; /窗口句柄,程序可以用父窗口的句柄或用空指針 SQLCHAR *InConnectionString; /一個指向連接字符串的指針 SQLSMALLINT StringLength1,

36、 /連接字符串長度 SQLCHAR *OutConnectionString; /一個指向連接字符串的指針 SQLSMALLINT BufferLength; /存放連接字符串的緩沖區(qū)的長度 SQLSMALLINT *StringLength2Ptr; /返回的連接字符串中的字符數(shù) SQLUSMALLINT DriverCompletion /額外的連接信息,可能的取值:SQL_DRIVER_PROMPT、SQL_DRIVER_COMPLETE、SQL_DRIVER_COMPLETE_REQUIRED、 SQL_DRIVER_NOPROMPT); (3) SQLBrowseConnect 函數(shù)

37、SQLBrowseConnect支持以一種迭代的方式獲取到數(shù)據(jù)源的連接,直到最后建立連接。它基于客戶機(jī)/服務(wù)器體系結(jié)構(gòu),因此本地數(shù)據(jù)庫(如Microsoft Access)不支持該函數(shù)。 一般,只提供部分連接信息,如果足以建立到數(shù)據(jù)源的連接,則成功建立連接,否則返回SQL_NEED_DATA,并在OutConnectionString參數(shù)中返回所需要的信息。其定義如下: SQLRETURN SQLBrowseConnect( SQLHDBC ConnectionHandle, /連接句柄 SQLCHAR *InConnectionString, /指向輸入字符串的指針 SQLSMALLINT

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

39、(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv); if(m_retcode != SQL_SUCCESS) & (m_retcode != SQL_SUCCESS_WITH_INFO) ) AfxMessageBox(“分配(fnpi)環(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_ret

40、code != SQL_SUCCESS) & (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv, SQL_HANDLE_ENV, “設(shè)置(shzh)odbc版本號時失??!”); return FALSE; /*分配(fnpi)連接句柄*/ m_retcode = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc); if(m_retcode != SQL_SUCCESS) & (m_retcode != SQL_SUCCESS_WITH_INFO) ReportError(m_henv,

41、SQL_HANDLE_ENV, “分配連接句柄失?。 ?;return FALSE; /*連接數(shù)據(jù)庫*/ 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ù)庫失??!”); r

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

43、AllocHandle函數(shù)分配的。下面的代碼聲明了一個存放語句句柄的變量m_hstmt,在函數(shù)中提供該變量的地址指針、所使用的連接句柄m_hdbc以及選項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ù)SQLGe

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

45、要執(zhí)行的SQL語句 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_hst

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

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

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

49、tType, /參數(shù)類型,可為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ù) S

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

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

52、Number, /標(biāo)識要綁定的列號。數(shù)據(jù)列號從0開始升序排列,其中第0列用作書簽,則列號從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(SQLHST

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

54、度上減輕網(wǎng)絡(luò)負(fù)載。 要使用塊光標(biāo),應(yīng)完成以下工作: 設(shè)定行集大小 綁定行集緩沖區(qū) 設(shè)定語句句柄屬性 取行行集結(jié)果 塊光標(biāo)返回多行記錄,應(yīng)用程序必須把這多行的數(shù)據(jù)綁定到某些數(shù)據(jù)組中,這些數(shù)據(jù)組稱為行集緩沖區(qū)。綁定方式有兩種,列方式和行方式。 (4) ODBC光標(biāo)庫 有些應(yīng)用程序不支持可滾動光標(biāo)和塊光標(biāo),ODBC SDK提供了一個光標(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_SUCCES

56、S) & (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 = SQLFetch(hstmt); if(retcode

57、 = SQL_ERROR | retcode = SQL_SUCCESS_WITH_INFO) /出錯,輸出錯誤,返回 show_error(); if(retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) fprintf(out, “%-*s %-5d %*s”, NAME_LEN-1, szName, sCustID, PHONE_LEN-1,szPhone); else break; 記錄的添加(tin ji)、刪除和更新 應(yīng)用程序?qū)?shù)據(jù)源的數(shù)據(jù)更新可以通過3種方式實現(xiàn):通過SQLExecDirect函數(shù)使用相應(yīng)(xingyng

58、)的SQL語句在數(shù)據(jù)源上執(zhí)行,調(diào)用SQLSetPos函數(shù)實現(xiàn)記錄集的定義更新,調(diào)用SQLBulkOperations函數(shù)實現(xiàn)數(shù)據(jù)的更新。 直接在數(shù)據(jù)源上執(zhí)行SQL語句的方式可以適用于任何的ODBC數(shù)據(jù)源,但是,對于后兩種更新(gngxn)方式,有的數(shù)據(jù)源并不支持,應(yīng)用程序可以調(diào)用函數(shù)SQLGetInfo確定數(shù)據(jù)源是否支持著兩種方式。 1、 直接執(zhí)行SQL語句在Demo1中專門有一個函數(shù)負(fù)責(zé)執(zhí)行SQL語句,其代碼如下: BOOL CMyODBC:ExeSqlDirect(const char *cpSqlStmt) SQLHSTMT hstmt; if(this-m_hdbc = NULL) A

59、fxMessageBox(“沒有連接數(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; /直接執(zhí)行SQL語句 m_retcode = SQLExecDirect(hstmt, (unsigned char *)cpSqlStmt, SQL_NTS); if(m_retco

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論