代碼如下:
//所有的ODBC函數都以SQL開始
#include <conio.h>//getch()
#include <stdio.h>
#include <afxwin.h>//// MFC core and standard components
#include <sqlext.h> //包含有擴展的ODBC的定義
#include <sql.h> //包含有基本的ODBC API的定義
#include <odbcinst.h>
#pragma comment(lib, "odbc32.lib")
#pragma comment(lib, "odbccp32.lib")//SQLConfigDataSource()函數
//#include "sqltypes.h"
//#include "sqlucode.h"
//#include "odbcss.h"
int main(int argc, char* argv[])
{
?
?SQLRETURN sr=SQL_SUCCESS;
?SQLHENV? hEnv=0; //分配odbc環境
?SQLHDBC? hDbc=0;//
?SQLHSTMT hStmt;//
?//
?SQLINTEGER iID;//第一列
?SQLCHAR tmJoin[20];//第二列
??? SQLCHAR szName[10];//第三列
?SQLREAL fTall;//第四列
?SQLINTEGER cbID,cbJoin,cbName,cbTall;//保存得到的數據的長度
?//
?int i=0;
?SQLCHAR?? SqlState[6];
?SQLINTEGER NativeError;
?SQLCHAR ErrMsg[SQL_MAX_MESSAGE_LENGTH];
?//
?char szDSN[] = "TestDB";//ODBC數據源
?char szUID[] = "sa"; //SQL用戶
?char szPWD[] = ""; //口令
??? LPCSTR svSQL="select * from [ApiOdbc]";
?//創建ODBC句柄,分配odbc環境
?/*對于任何ODBC應用程序來說,第一步的工作是裝載驅動程序管理器,然后初始化ODBC環境,分配環境句柄。
??? 首先,程序中聲明一個SQLHENV類型的變量,然后調用函數SQLAllocHandle,向其中傳遞分配的上述SQLHENV類型
?的變量地址和SQL_HANDLE_ENV選項。如下代碼所示:SQLHENV henv;SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv);
??? 執行該調用語句后,驅動程序分配一個結構,該結構中存放環境信息,然后返回對應于該環境的環境句柄。
?SQLRETURN SQLAllocHandle(
??????SQLSMALLINT?? HandleType,
??????SQLHANDLE???? InputHandle,第二個參數為輸入句柄
??????SQLHANDLE *?? OutputHandlePtr 第三個參數為輸出句柄
???????);??
?SQL_HANDLE_ENV:申請環境句柄。
??? SQL_HANDLE_DBC:申請數據庫連接句柄
?SQL_HANDLE_STMT:申請SQL語句句柄,每次執行SQL語句都申請語句句柄,并且在執行完成后釋放*/
???
?//利用動態鏈接庫Odbcinst.dll動態創建DSN
?if(SQLConfigDataSource(NULL,ODBC_ADD_SYS_DSN,"SQL Server","DSN=TestDB\0Description=TestAPIODBC\0SERVER=(local)\0DATABASE=TestDB"))
?{
??printf("32位ODBC數據源配置 Success!\n\n");
?}
???
?sr = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&hEnv);
?if(sr==SQL_SUCCESS||sr==SQL_SUCCESS_WITH_INFO)
?{
??printf("1~~創建環境句柄SQLAllocHandle Success!\n");
?}
??? //設定odbc版本,將ODBC設置成為版本3,否則某些ODBC API 函數不能被支持
?sr = SQLSetEnvAttr(hEnv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3,SQL_IS_INTEGER);
?if(sr==SQL_SUCCESS||sr==SQL_SUCCESS_WITH_INFO)
?{
??printf("2~~SQLSetEnvAttr Success!\n");
?}
?//分配odbc連接句柄
?/*分配環境句柄后,在建立至數據源的連接之前,我們必須分配一個連接句柄,每一個到數據源的連接對應于一個連接句柄。
??? 首先,程序定義了一個SQLHDBC類型的變量,用于存放連接句柄,然后調用SQLAllocHandle函數分配句柄。如下代碼所示:
??? SQLHDBC hdbc;SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);henv為環境句柄。*/
??? sr = SQLAllocHandle(SQL_HANDLE_DBC,hEnv,&hDbc);
??? if(sr==SQL_SUCCESS||sr==SQL_SUCCESS_WITH_INFO)
?{
??printf("3~~創建連接句柄SQL_HANDLE_DBC Success!\n");
?}
??? //連接連接屬性
?/*當連接句柄分配完成后,我們可以設置連接屬性,所有的連接屬性都有缺省值,但是我們可以通過調用函數SQLSetConnectAttr()
?來設置連接屬性。用函數SQLGetConnectAttr()獲取這些連接屬性。函數格式如下:
?SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr,SQLINTEGER StringLength);
?SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr,SQLINTEGER StringLength);
??? 應用程序可以根據自己的需要設置不同的連接屬性。*/
?sr = SQLSetConnectAttr(hDbc,SQL_ATTR_LOGIN_TIMEOUT,(void*)7,0);
??? if(sr==SQL_SUCCESS||sr==SQL_SUCCESS_WITH_INFO)
?{
??printf("4~~設置連接屬性SQLSetConnectAttr Success!\n");
?}
?
?//連接
?/*完成對連接屬性的設置之后,就可以建立到數據源的連接了。對于不同的程序和用戶接口,可以用不同的函數建立連接:
?SQLConnect、SQLDriverConnect、SQLBrowseConnect。
??? SQLConnect該函數提供了最為直接的程序控制方式,我們只要提供數據源名稱、用戶ID和口令,就可以進行連接了。
??? 函數格式:SQLRETURN SQLConnect(SQLHDBC ConnectionHandle,SQLCHAR ServerName,SQLSMALLINT NameLength1,SQLCHAR UserName,SQLSMALLINT NameLength2,SQLCHAR *Authentication,SQLSMALLINT NameLength3);
??? 參數:ConnectionHandle 連接句柄,ServerName 數據源名稱,NameLength1 數據源名稱長度,UserName 用戶ID
?NameLength2 用戶ID長度,Authentication 用戶口令,NameLength3 用戶口令長度
?返回值:SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
?成功返回SQL_SUCCESS*/
?sr = SQLConnect(hDbc,(SQLCHAR *)szDSN, SQL_NTS,(SQLCHAR *)szUID,SQL_NTS,(SQLCHAR *)NULL,SQL_NTS);
??? /*如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值*/
?if(sr != SQL_SUCCESS && sr != SQL_SUCCESS_WITH_INFO)
?{
??TRACE("ERROR");
??while(SQLGetDiagRec(SQL_HANDLE_DBC,hDbc,i,SqlState, &NativeError,ErrMsg,sizeof(ErrMsg),NULL)!= SQL_NO_DATA)
???TRACE("Diag : %d SQLSTATE :%s NativeError : %d ,ErrMsg : %s\n",i ++,SqlState,NativeError,ErrMsg);
?}
?else
?{
??printf("5~~連接Connect Success!\n");
??? }
?//分配語句句柄sr = SQLAllocStmt(hDbc,&hStmt);SQLAllocStmt() 已被廢棄,且替換為 SQLAllocHandle();
?sr=SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
??? if(sr == SQL_SUCCESS||sr == SQL_SUCCESS_WITH_INFO)
?{
??printf("6~~分配語句句柄SQL_HANDLE_STMT Success!\n");
?}
??? //執行SQL查詢語句
?sr=SQLExecDirect(hStmt,(UCHAR *)svSQL,SQL_NTS);
??? if (sr == SQL_SUCCESS||sr == SQL_SUCCESS_WITH_INFO)
??? {
??????? printf("7~~執行SQL查詢語句SQLExecDirect Success!\n");
??printf("\n-------------get date from db-------------\n");
??while ((sr=SQLFetch(hStmt))!=SQL_NO_DATA)
??{
???//執行SQL語句后遍歷結果集來得到數據
???SQLGetData(hStmt, 1, SQL_C_ULONG, &iID, 0, &cbID);
???SQLGetData(hStmt, 2, SQL_C_CHAR,? tmJoin, 20, &cbJoin);//datatime類型放在SQLCHAR數組中,數組length要足夠
???SQLGetData(hStmt, 3, SQL_C_CHAR,? szName, 10, &cbName);
???SQLGetData(hStmt, 4, SQL_C_FLOAT, &fTall, 0, &cbTall);
???printf("%d~~~%s~~~%s~~~%f\n",iID,tmJoin,szName,fTall);
??}
?}
??? //釋放句柄
?if(hStmt!=SQL_NULL_HANDLE)
?{
??SQLFreeHandle( SQL_HANDLE_STMT, hStmt );
???? hStmt=NULL;
?}
?if(hDbc != SQL_NULL_HANDLE)
?{
??sr = SQLDisconnect(hDbc);
??SQLFreeHandle(SQL_HANDLE_DBC,hDbc);
??hDbc=NULL;
?}
?if(hEnv != SQL_NULL_HANDLE)
?{
??SQLFreeHandle(SQL_HANDLE_ENV,hEnv);
??hEnv=NULL;
?}
?//
?printf("API ODBC Success!\n");
?system("PAUSE");
?return 0;
}
?
?
?
?