代码如下:
//所有的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;
}