资源描述
ODBC编程培训教程
ODBC编程培训教程
1 概述 3
2 ODBC API访问数据库 3
2.1 ODBC简要介绍 3
2.2 ODBC结构 3
2.3 ODBC进行数据库开发基础知识简介 4
2.3.1 建立odbc dsn 5
2.3.2 使用ODBC所需要的文件 7
2.3.3 SQL语句的执行方式 7
2.3.4 获取SQL语句的执行结果 7
2.3.5 程序执行的基本流程 8
2.3.6 数据类型定义 9
2.3.7 ODBC句柄 13
2.4 为本章的例程创建DSN与数据库表 13
2.5 ODBC的基本功能介绍 13
2.5.1 所需要了解的ODBC API 13
2.6 ODBC的其他功能介绍 19
2.6.1 ODBC连接句柄的参数设置 19
2.6.2 ODBC语句句柄的参数设置 20
2.6.3 ODBC中使用可以滚动的光标 20
2.6.4 ODBC的 参数邦定 22
2.6.5 SQL的准备和执行 24
2.6.6 BLOB字段的更新和查询 26
2.6.7 ODBC对事务的支持 28
3 结束语 29
1 概述
本文主要介绍ODBC 的功能,所有内容都与ODBC 3.X版本兼容。大致包括:
l 使用ODBC进行数据库连接
l 利用ODBC直接执行SQL语句
l ODBC光标类型介绍
l 利用滚动光标或非滚动光标进行结果集查询
l SQL语句的准备执行方式
l BLOB数据字段的查询和修改
l ODBC对事务的支持
本文的数据库利用了GBase,ODBC在使用时是与数据库无关的所以所有例程都可以运行在其他数据库上,例如Oracle。只是有些sql语句的语法需要修改。
2 ODBC API访问数据库
2.1 ODBC简要介绍
ODBC(Open Database Connectivity)是由微软公司提出的一个用于访问数据库的统一界面标准,随着客户机/服务器体系结构在各行业领域广泛应用,多种数据库之间的互连访问成为一个突出的问题,而ODBC成为目前一个强有力的解决方案。ODBC之所以能够操作众多的数据库,是由于当前绝大部分数据库全部或部分地遵从关系数据库概念,ODBC看待这些数据库时正是着眼了这些共同点。虽然支持众多的数据库,但这并不意味ODBC会变得复杂,ODBC是基于结构化查询语言(SQL),使用SQL可大大简化其应用程序设计接口(API),由于ODBC思想上的先进性,而且没有同类标准或产品与之竞争,因而越来越受到众多厂家和用户的青睐。目前,ODBC已经成为客户机/服务器系统中的一个重要支持技术。
2.2 ODBC结构
图2.1显示了ODBC的结构。
图2.1
应用程序(Application)
应用程序本身不直接与数据库打交道,主要负责处理并调用ODBC函数,发送对数据库的SQL请求及取得结果。
驱动程序管理器(Driver Manager )
驱动程序管理器是一个带有输入程序的动态链接库(DLL),主要目的是加载驱动程序,处理ODBC调用的初始化调用,提供ODBC调用的参数有效性和序列有效性。
驱动程序(Driver)
驱动程序是一个完成ODBC函数调用并与数据库相互影响的DLL,这些驱动程序可以处理对于特定的数据的数据库访问请求。对于应用驱动程序管理器送来的命令,驱动程序再进行解释形成自己的数据库所能理解的命令。驱动程序将处理所有的数据库访问请求,对于应用程序来讲不需要关注所使用的是本地数据库还上网络数据库。
2.3 ODBC进行数据库开发基础知识简介
2.3.1 建立odbc dsn
DSN(Data Source Name)是用于指定ODBC与相关的驱动程序相对应的一个入口,所有DSN的信息由系统进行管理,一般来讲当应用程序要使用ODBC访问数据库时,就需要指定一个DSN以便于连接到一个指定的ODBC驱动程序。在控制面板中打开ODBC管理器,回看到如图2.2的界面。【开始】->【设置】 -> 【控制面板】-> 【管理工具】 ->打开 【数据源(ODBC)】
DSN共分为三类:
用户DSN:对当前登录用户可见,只能够用于当前计算机。
系统DSN:对当前系统上所有用户可见,包括NT中的服务。
文件DSN:DSN信息存放在文件中,对能够访问到该文件的用户可见。
对于文件DSN来讲这些信息存放在文件中,对于用户DSN和系统DSN来讲这些信息存放在注册表内。
进入【系统 DSN】页显示如下:
图2.2
单击上图中的【添加】按钮后显示如下:
图2.3.1
从上图驱动列表中选择相应数据库产品的ODBC驱动,单击【完成】后显示如下(选择GBase ODBC3.51 Driver):
图2.3.2
依次填写正确的数据源信息,上图中的数据源名项用户可以自定,描述项内容可以忽略,服务器项是服务器端IP或主机名称,用户和密码为在数据库中已创建的用户名和密码,数据库项为服务器端的数据库名称一正确填写完上图中的所有项,。点击[测试],可以测试填写的信息是否正确,单击[确定] 关闭此窗体,完成该数据库dsn项的配置。
2.3.2 使用ODBC所需要的文件
你需要下面的文件:
sql.h:包含有基本的ODBC API的定义。
sqlext.h:包含有扩展的ODBC的定义。
odbc32.lib:库文件。
这些文件在VC6,VC7都已经随开发工具提供了,不需要另外安装。
此外所有的ODBC函数都以SQL开始,例如SQLExecute,SQLAllocHandle。
2.3.3 SQL语句的执行方式
在ODBC中SQL语句的执行方式分为两种,直接执行和准备执行。
直接执行是指由程序直接提供SQL语句,例如:Select * from test_table并调用SQLExecDirect执行,准备执行是指先提供一个SQL语句并调用SQLPrepare,然后当语句准备好后调用SQLExecute执行前面准备好的语句。准备执行多用于数据插入和数据删除,在进行准备时将由ODBC驱动程序对语句进行分析,在实际执行时可以避免进行SQL语句分析所花费的时间,所以在进行大批量数据操作时速度会比直接执行有明显改善。在后面的章节中我会详细介绍准备执行与行列绑定与参数替换的用法。
2.3.4 获取SQL语句的执行结果
对于SQL查询语句,ODBC会返回一个光标,与光标对应的是一个结果集合(可以理解为一个表格)。开发人员利用光标来浏览所有的结果,你可以利用ODBC API函数移动光标,并且获取当前光标指向的行的列字段的数值。此外还可以通过光标来对光标当前所指向的数据进行修改,而修改会直接反映到数据库中。
对于数据更新语句,如插入,删除和修改,在执行后可以得到当前操作所影响的数据的行数。
2.3.5 程序执行的基本流程
图2.4
上图是一个基本的使用ODBC API的一个流程,你现在并不理解上面所有的函数的作用,这没有关系。但希望能够通过这幅图给你一个最初的映象,那就是使用ODBC API开发并不复杂。
2.3.6 数据类型定义
在使用ODBC开发时一个重要的问题就是数据转换的问题,在ODBC中存在下面的几类数据:
A.数据库中SQL语言表达数据的类型
B.ODBC中表达数据的类型
C. C语言中表达数据的类型
在程序运行过程中数据需要经历两次转换:C语言的数据或结构类型与ODBC的数据类型的转换,ODBC与SQL间数据类型的转换。所以ODBC所定义的数据类型起到了中间桥梁的作用,在ODBC的驱动程序调用自己的DBMS数据库访问接口时就需要对数据类型进行转换。我们所需要关注的是C语言的数据类型和ODBC数据类型间的转换关系。
ODBC数据类型名称
SQL语言数据类型名称
SQL_CHAR
CHAR(n)
SQL_VARCHAR
VARCHAR(n)
SQL_LONGVARCHAR
LONG VARCHAR
SQL_WCHAR
WCHAR(n)
SQL_WVARCHAR
VARWCHAR(n)
SQL_WLONGVARCHAR
LONGWVARCHAR
SQL_DECIMAL
DECIMAL(p,s)
SQL_NUMERIC
NUMERIC(p,s)
SQL_SMALLINT
SMALLINT
SQL_INTEGER
INTEGER
SQL_REAL
REAL
SQL_FLOAT
FLOAT(p)
SQL_DOUBLE
DOUBLE PRECISION
SQL_BIT
BIT
SQL_TINYINT
TINYINT
SQL_BIGINT
BIGINT
SQL_BINARY
BINARY(n)
SQL_VARBINARY
VARBINARY(n)
SQL_LONGVARBINARY
LONG VARBINARY
SQL_TYPE_DATE[6]
DATE
SQL_TYPE_TIME[6]
TIME(p)
SQL_TYPE_TIMESTAMP[6]
TIMESTAMP(p)
SQL_GUID
GUID
图2.5
使用C/C++语言开发,那么必定会在与ODBC语言间存在数据的转换的问题,因为ODBC所存在的一些数据类型在C语言中是不存在的。在ODBC以宏定义的方式定义了C语言和ODBC中使用的数据类型:
C语言数据类型名称
ODBC 数据类型定义
C语言实际类型
SQL_C_CHAR
SQLCHAR *
unsigned char *
SQL_C_SSHORT[j]
SQLSMALLINT
short int
SQL_C_USHORT[j]
SQLUSMALLINT
unsigned short int
SQL_C_SLONG[j]
SQLINTEGER
long int
SQL_C_ULONG[j]
SQLUINTEGER
unsigned long int
SQL_C_FLOAT
SQLREAL
float
SQL_C_DOUBLE
SQLDOUBLE, SQLFLOAT
double
SQL_C_BIT
SQLCHAR
unsigned char
SQL_C_STINYINT[j]
SQLSCHAR
signed char
SQL_C_UTINYINT[j]
SQLCHAR
unsigned char
SQL_C_SBIGINT
SQLBIGINT
_int64[h]
SQL_C_UBIGINT
SQLUBIGINT
unsigned _int64[h]
SQL_C_BINARY
SQLCHAR *
unsigned char *
SQL_C_BOOKMARK[i]
BOOKMARK
unsigned long int[d]
SQL_C_VARBOOKMARK
SQLCHAR *
unsigned char *
SQL_C_TYPE_DATE[c]
SQL_DATE_STRUCT
struct tagDATE_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
} DATE_STRUCT;[a]
SQL_C_TYPE_TIME[c]
SQL_TIME_STRUCT
struct tagTIME_STRUCT {
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
} TIME_STRUCT;[a]
SQL_C_TYPE_TIMESTAMP[c]
SQL_TIMESTAMP_STRUCT
struct tagTIMESTAMP_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
SQLUINTEGER fraction;[b]
} TIMESTAMP_STRUCT;[a]
SQL_C_NUMERIC
SQL_NUMERIC_STRUCT
struct tagSQL_NUMERIC_STRUCT {
SQLCHAR precision;
SQLSCHAR scale;
SQLCHAR sign[g];
SQLCHAR val[SQL_MAX_NUMERIC_LEN];[e], [f]
} SQL_NUMERIC_STRUCT;
SQL_C_GUID
SQLGUID
struct tagSQLGUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} SQLGUID;[k]
图2.6
所以在ODBC的开发过程中不要使用int , float 之类的C语言的实际类型来定义变量而应该使用ODBC定义的数据类型来定义变量,如:SQLINTEGER,SQLFLOAT。
2.3.7 ODBC句柄
ODBC中的句柄分为三类:环境句柄,数据库连接句柄,SQL语句句柄。
通过图2.3.4看出,在使用ODBC功能时必须先申请环境句柄,然后在环境句柄的基础上创建数据库连接,最后在数据连接的基础上执行SQL语句。
2.4 为本章的例程创建DSN与数据库表
为了后面的例子能够顺利执行,请创建一个名称为“gbase”的DSN,并且使用下面的语句在数据库中创建表和插入基本的数据,这个例子和以后的例子中我们使用GBase作为数据库,你需要连接到GBase上执行下面的语句来创建表和插入数据。
Create table test_t1(iID int primary key , tmJoin datetime , szName varchar(40) ,fTall float );
Insert into test_t1 values(1, '2002-1-1 15:25' , 'user_1',1.56 );
Insert into test_t1 values(2, '2002-1-2 12:25' , 'user_2',1.53 );
Insert into test_t1 values(3, '2002-1-3 13:25' , 'user_3',1.76 );
2.5 ODBC的基本功能介绍
2.5.1 所需要了解的ODBC API
2.5.1.1 SQLAllocHandle 创建ODBC句柄
SQLRETURN SQLAllocHandle(
SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE * OutputHandlePtr);
第一个参数HandleType的取值可以为:
SQL_HANDLE_ENV:申请环境句柄。
SQL_HANDLE_DBC:申请数据库连接句柄。
SQL_HANDLE_STMT:申请SQL语句句柄,每次执行SQL语句都申请语句句柄,并且在执行完
成后释放。
第二个参数为输入句柄,第三个参数为输出句柄,也就是是你在第一参数指定的需要申请的句柄。
前面已经说明,在使用ODBC功能时必须先申请环境句柄,然后在环境句柄的基础上创建数据库连接,最后在数据连接的基础上执行SQL语句。所以可能的调用方式有三种。
SQLAllocHandle(SQL_HANDLE_ENV,NULL,&hEnv);
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
SQLAllocHandle(SQL_HANDLE_DBC,hEnv,&hDBC);
SQLAllocHandle(SQL_HANDLE_STMT,hDBC,&hSTMT);
请注意,在创建环境句柄后请务必调用:
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
将ODBC设置成为版本3,否则某些ODBC API 函数不能被支持。
2.5.1.2 ODBC API的返回值
ODBC API的返回值定义为:SQLRETURN。在成功时返回值为:SQL_SUCCESS, SQL_SUCCESS_WITH_INFO;在失败时返回错误代码。
一点需要注意的是如果ODBC返回值为:SQL_SUCCESS_WITH_INFO并不表明执行完全成功,而是表明执行成功但是带有一定错误信息。当执行错误时ODBC返回的是一个错误信息的结果集,你需要遍历结果集合中所有行,这点和后面讲到的查询SQL语句执行结果集的思路很类似。
在ODBC可以利用SQLGetDiagRec来得到错误描述信息:
SQLRETURN SQLGetDiagRec(
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT RecNumber,
SQLCHAR * Sqlstate,
SQLINTEGER * NativeErrorPtr,
SQLCHAR * MessageText,
SQLSMALLINT BufferLength,
SQLSMALLINT * TextLengthPtr);
RecNumber:指明需要得到的错误状态行,从1开始逐次增大。
Sqlstate,NativeErrorPtr,MessageText:返回错误状态,错误代码和错误描述。
BufferLength:指定MessageText的最大长度。
TextLengthPtr:指定返回的MessageText中有效的字符数。
函数的返回值可能为:SQL_SUCCESS,SQL_SUCCESS_WITH_INFO,SQL_ERROR,SQL_INVALID_HANDLE,SQL_NO_DATA。在没有返回错误的情况下你需要反复调用此函数,并顺次增大RecNumber参数的值,直到函数返回SQL_NO_DATA,以得到所有的错误描述。
示例,得到STMT句柄上的错误信息:
SQLCHAR SqlState[6],SQLStmt[100],Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT i, MsgLen;
int i = 1;
while ((rc2 = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, SqlState, &NativeError, Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA)
{
//显示错误的代码
i++;
}
2.5.1.3 SQLConnect 连接数据库
SQLRETURN SQLConnect(
SQLHDBC ConnectionHandle,
SQLCHAR * ServerName,
SQLSMALLINT NameLength1,
SQLCHAR * UserName,
SQLSMALLINT NameLength2,
SQLCHAR * Authentication,
SQLSMALLINT NameLength3);
ConnectionHanlde:为DBC句柄,也就是前面提到利用SQLAllocHandle(SQL_HANDLE_DBC,hEnv,&hDBC);申请的句柄。
ServerName:为ODBC的DSN名称
NameLength1:指明参数ServerName数据的长度。
UserName:数据库用户名。
NameLength2:指明参数UserName数据的长度。
Authentication:数据库用户密码。
NameLength3:指明参数Authentication数据的长度。
关于ServerName,UserName,Authentication参数长度可以直接指定也可以指定为SQL_NTS表明参数是以NULL字符结尾。
示例代码:
retcode = SQLConnect(hdbc, (SQLCHAR*) "gbase", SQL_NTS,(SQLCHAR*) "user", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
2.5.1.4 SQLExecDirect 直接执行SQL语句
SQLRETURN SQLExecDirect(
SQLHSTMT StatementHandle,
SQLCHAR * StatementText,
SQLINTEGER TextLength);
StatementHandle:SQL语句句柄,也就是前面提到的利用:
SQLAllocHandle(SQL_HANDLE_STMT,hDBC,&hSTMT);申请的句柄。
StatementText:SQL语句。
TextLength:参数StatementText的长度,可以使用SQL_NTS表示字符串以NULL字符结尾。
如果函数执行成功,你将会得到一个结果集,否则将返回错误信息。
SQLExecDirect函数除可以执行 Select 语句外,还可以执行Insert,Update,Delete 语句,在执行修改SQL语句后可以利用SQLRowCount 函数来得到被更新的记录的数量。
2.5.1.5 SQLFetch 移动光标
SQLRETURN SQLFetch(SQLHSTMT StatementHandle);
在你调用SQLExecDirect执行SQL语句后,你需要遍历结果集来得到数据。StatementHandle是STMT句柄,此句柄必须是被执行过。
当调用SQLFetch 函数后,光标会被移动到下一条记录处,当光标移动到记录集的最后一条,函数将会返回SQL_NO_DATA。
要遍历所有的结果集可以利用下面的方法:
while(SQL_NO_DATA != SQLFetch(hstmt)) //移动光标,一直到集合末尾
{//得到结果
}
2.5.1.6 SQLGetData 得到光标处的某列的值
SQLRETURN SQLGetData(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLINTEGER BufferLength,
SQLINTEGER * StrLen_or_IndPtr);
StatementHanlde:STMT句柄。
ClumnNumber:列号,以1开始。
TargetType:数据缓冲区(TargetValuePtr)的C语言数据类型,请参照图2.6。
BufferLength:数据缓冲区(TargetValuePtr)的长度。
StrLen_or_IndPtr:返回当前得到的字段的字节长度。
下面是通过SQLFetch和SQLGetData得到记录集的例子:
//假设 SQL = SELECT CUSTID, NAME, PHONE FROM CUSTOMERS
SQLINTEGER sCustID
SQLCHAR szName[50], szPhone[50];
SQLINTEGER cbCustID,cbName, cbPhone;//用来保存得到的数据的长度
while (TRUE) {//循环得到所有行
retcode = SQLFetch(hstmt);//移动光标
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
printf(“error SQLFetch\n”);
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
/*得到当前光标处每列的值 */
SQLGetData(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);
//此处并没有指明BufferLength参数的值,是因为数据类型是定长的LONG型
SQLGetData(hstmt, 2, SQL_C_CHAR, szName, 50, &cbName);
SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, 50,&cbPhone);
printf(out, "%5d %s %s", sCustID, szName, szPhone);
} else {
break;
}
}
SQLGetData的另一个用处就是用于得到一些变长字段的实际长度,例如VARCHAR字段,TEXT字段。例如:
SQLGetData(hstmt, 2, SQL_C_CHAR, szName, 0, &cbName);
当你将 BufferLength 参数置为0,则会在 StrLen_or_IndPtr 参数中返回字段的实际长度。但请注意第四个参数必须是一个合法的指针,不能够为NULL。
此外在得到字段的值时还存在一个数据类型转换的问题,比如说数据库内的字段类型为:INTEGER,那么你可以使用SQL_C_INTEGER,SQL_C_CHAR,SQL_C_ULONG数据类型来得到该字段的值。图2.7就说明了所有可能存在的转换关系。
图2.7
参考前面的图2.5和图2.6就可以看出ODBC可以在SQL的数据类型和C的数据类型间提供转换。
请注意我讲解图2.5时提到的时ODBC数据类型和SQL语言数据类型之间的对应关系,而这里提到的是数据之间的转换关系。
图中用圆点标出的交叉点为允许的类型转换,其中实心圆点标出的是默认的数据转换类型,空心圆点标出的是允许的数据转换类型(允许并不表明一定可以,例如Char类型可以转换为SQL_C_INTEGER,但是并不是总能成功,当字符为’123’时可以转换为整数123,而字符为’odbc’时就不能成功)。例如数据库中的Char,VarChar类型默认都是对应SQL_C_CHAR类型。你还可以看到所有的数据库字段类型都可以转换为SQL_C_CHAR类型,例如整数123可以转换为”123”,而浮点数1.23可以转换为”1.23”,日期的2002年10月1日可以转换为”2002-10-1”。所以在初学ODBC并且对性能要求不是非常高时可以用字符类型来得到数据库字段的值,这样做会比较方便。
2.5.1.7 SQLNumResultCols 得到结果集中列数
SQLRETURN SQLNumResultCols(
SQLHSTMT StatementHandle,
SQLSMALLINT * ColumnCountPtr);
StatementHandle:STMT句柄
ColumnCountPtr:返回列数
2.5.1.8 SQLDescribeCol 得到结果集中列的描述
SQLRETURN SQLDescribeCol(
SQLHSTMT StatementHandle,
SQLSMALLINT ColumnNumber,
SQLCHAR * ColumnName,
SQLSMALLINT BufferLength,
SQLSMALLINT * NameLengthPtr,
SQLSMALLINT * DataTypePtr,
SQLUINTEGER * ColumnSizePtr,
SQLSMALLINT * DecimalDigitsPtr,
SQLSMALLINT * NullablePtr);
StatementHandle:STMT句柄。
ColumnNumber:需要得到的列的序号,从1开始计算。
ColumnName:得到列的名称。
BufferLength:指明ColumnName参数的最大长度。
NameLengthPtr:返回列名称的长度。
DataTypePtr:得到列的ODBC数据类型,请参照图2.5。
ColumnSizePtr:得到列的长度。
DecimalDigitsPtr:当该列为数字类型时返回小数点后数据的位数。
NullablePtr:指明该列是否允许为空值。
2.5.1.9 SQLRowCount 执行SQL语句后得到影响的行数
SQLRETURN SQLRowCount(
SQLHSTMT StatementHandle,
SQLINTEGER * RowCountPtr);
你可以通过SQLExecDirect执行SQL语句来插入,修改和删除数据,在执行插入,修改和删除的SQL语句后就可以通过SQLRowCount函数来得到被影响的数据的行数。
例如:Insert into test_t1 values(4, '2002-1-4 11:25' , 'user_4',1.86 );
2.6 ODBC的其他功能介绍
2.6.1 ODBC连接句柄的参数设置
在上一小节中提到了 SQLSetConnectAttr 这个函数,这里需要对这个函数进行一些简单的讲解,你可以通过调用 SQLSetConnectAttr 在数据库连接建立或建立后设置连接的一些属性。
SQLSetConnectAttr的函数原型如下:
SQLRETURN SQLSetConnectAttr(
SQLHDBC ConnectionHandle,
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
ConnectionHandle:提供DBC连接句柄。
Attribute:指定需要设置的属性类型,在这里设置为值SQL_ATTR_AUTOCOMMIT。
ValuePtr:提供参数值。
StringLength:指定参数的长度,当参数为整数是设置为SQL_IS_INTEGER,当参数为字符串时设置为字符串长度或者为SQL_NTS 。
这里讲一下常用的参数Attribute可能的取值和ValuePtr对应的取值:
Attribute
ValuePtr
作用
SQL_ATTR_CONNECTION_DEAD
提供一个合法的SQLINTEGER 指针作为输出参数
检查连接是否已经断开
返回:SQL_CD_TRUE表明连接已经断开,
SQL_CD_FALSE表明连接还保持。
SQL_ATTR_CONNECTION_TIMEOUT
设置一个合法的整数
建立与数据库连接时最大等待的超时秒数,ValuePtr设置为0表明不使用超时控制。
SQL_ATTR_LOGIN_TIMEOUT
设置一个合法的整数
建立与数据库用户登录时最大等待的超时秒数,ValuePtr设置为0表明不使用超时控制。
SQL_ATTR_TRACE
整数,取值为:SQL_OPT_TRACE_OFF,SQL_OPT_TRACE_ON
设置是否跟踪ODBC驱动程序中函数的调用。
SQL_ATTR_TRACEFILE
设置一个合法的文件名字符串,表明记录跟踪记录的文件名。
设置记录函数调用的文件名称。
2.6.2 ODBC语句句柄的参数设置
如同数据库连接句柄一样,语句句柄也可以设置参数。函数为:
SQLRETURN SQLSetStmtAttr(
SQLHSTMT StatementHandle,
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
ConnectionHandle:提供STMT连接句柄。
Attribute:指定需要设置的属性类型,在这里设置为值SQL_ATTR_AUTOCOMMIT。
ValuePtr:提供参数值。
StringLength:指定参数的长度,当参数为整数是设置为SQL_IS_INTEGER,当参数为字符串时设置为字符串长度或者为SQL_NTS 。
这里讲一下常用的参数Attribute可能的取值和ValuePtr对应的取值:
Attribute
ValuePtr
作用
SQL_ATTR_ASYNC_ENABLE
整数,取值为:SQL_ASYNC_ENABLE_OFF,SQL_ASYNC_ENABLE_ON
是否使用异步执行功能
SQL_ATTR_QUERY_TIMEOUT
设置一个合法的整数
SQL语句执行时的超时秒数,设置为0表示无超时
SQL_ATTR_CURSOR_TYPE
整数,取值为:SQL_CURSOR_FORWARD_ONLY,SQL_CURSOR_STATIC,SQL_CURSOR_DYNAMIC,SQL_CURSOR_KEYSET_DRIVEN
设置光标的类型
2.6.3 ODBC中使用可以滚动的光标
从上面的函数SQLSetStmtAttr可以看到我们在ODBC中可以使用不同的光标类型,那么这些光标之间有什么区别。
向前光标:SQL_CURSOR_FORWARD_ONLY,光标仅仅向前滚动。
静态光标:SQL_CURSOR_STATIC,结果集的数据是静态的,这就是说明在执行查询后,返回的结果集的数据不会再改变,即使是有其他程序更新了数据库中的记录,结果集中的记录也不会发生改变。
动态光标:SQL_CURSOR_DYNAMIC,在光标打开以后,当结果集中
展开阅读全文