ODBC
ODBC接口是一套提供给用户的API函数,本节将对部分常用接口做具体描述,若涉及其他接口可参考msdn(网址:https://msdn.microsoft.com/en-us/library/windows/desktop/ms714177(v=vs.85).aspx)中ODBC Programmer's Reference项的相关内容。
SQLAllocEnv
在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocEnv已被SQLAllocHandle代替。有关详细信息请参阅7.2.3SQLAllocHandle。
SQLAllocConnect
在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocConnect已被SQLAllocHandle代替。有关详细信息请参阅7.2.3SQLAllocHandle。
SQLAllocHandle
功能描述
分配环境、连接、语句或描述符的句柄,它替代了ODBC 2.x函数SQLAllocEnv、SQLAllocConnect及SQLAllocStmt。
原型
SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE *OutputHandlePtr);
参数
表7-15 SQLAllocHandle参数
关键字 | 参数说明 |
---|---|
HandleType | 由SQLAllocHandle分配的句柄类型。必须为下列值之一:
- SQL_HANDLE_ENV(环境句柄) - SQL_HANDLE_DBC(连接句柄) - SQL_HANDLE_STMT(语句句柄) - SQL_HANDLE_DESC(描述句柄) 申请句柄顺序为,先申请环境句柄,再申请连接句柄,最后申请语句句柄,后申请的句柄都要依赖它前面申请的句柄。 |
InputHandle | 将要分配的新句柄的类型。
- 如果HandleType为SQL_HANDLE_ENV,则这个值为SQL_NULL_HANDLE。 - 如果HandleType为SQL_HANDLE_DBC,则这一定是一个环境句柄。 - 如果HandleType为SQL_HANDLE_STMT或SQL_HANDLE_DESC,则它一定是一个连接句柄。 |
OutputHandlePtr | 输出参数:一个缓冲区的指针,此缓冲区以新分配的数据结构存放返回的句柄。 |
返回值
SQL_SUCCESS:表示调用正确,
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息,
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等、
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当分配的句柄并非环境句柄时,如果SQLAllocHandle返回的值为SQL_ERROR,则它会将OutputHandlePtr的值设置为SQL_NULL_HDBC、SQL_NULL_HSTMT或SQL_NULL_HDESC。之后,通过调用带有适当参数的7.2.19SQLGetDiagRec,其中HandleType和Handle被设置为IntputHandle的值,可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLAllocStmt
在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocStmt已被SQLAllocHandle代替。有关详细信息请参阅7.2.3SQLAllocHandle。
SQLBindCol
功能描述
将应用程序数据缓冲区绑定到结果集的列中。
原型
SQLRETURN SQLBindCol(SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN *StrLen_or_IndPtr);
参数
表7-16 SQLBindCol参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄。 |
ColumnNumber | 要绑定结果集的列号。起始列号为0,以递增的顺序计算列号,第0列是书签列。若未设置书签页,则起始列号为1。 |
TargetType | 缓冲区中C数据类型的标识符。 |
TargetValuePtr | 输出参数:指向与列绑定的数据缓冲区的指针。SQLFetch函数返回这个缓冲区中的数据。如果此参数为一个空指针,则StrLen_or_IndPtr是一个有效值。 |
BufferLength | TargetValuePtr指向缓冲区的长度,以字节为单位。 |
StrLen_or_IndPtr | 输出参数:缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLBindCol返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLBindParameter
功能描述
将一条SQL语句中的一个参数标志和一个缓冲区绑定起来。
原型
SQLRETURN SQLBindParameter(SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValuetType,
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
SQLLEN *StrLen_or_IndPtr);
参数
表7-17 SQLBindParameter
关键词 | 参数说明 |
---|---|
StatementHandle | 语句句柄。 |
ParameterNumber | 参数序号,起始为1,依次递增。 |
InputOutputType | 输入输出参数类型。 |
ValueType | 参数的C数据类型。 |
ParameterType | 参数的SQL数据类型。 |
ColumnSize | 列的大小或相应参数标记的表达式。 |
DecimalDigits | 列的十进制数字或相应参数标记的表达式。 |
ParameterValuePtr | 指向存储参数数据缓冲区的指针。 |
BufferLength | ParameterValuePtr指向缓冲区的长度,以字节为单位。 |
StrLen_or_IndPtr | 缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLBindParameter返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLColAttribute
功能描述
返回结果集中一列的描述符信息。
原型
SQLRETURN SQLColAttibute(SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLUSMALLINT FieldIdentifier,
SQLPOINTER CharacterAtrriburePtr,
SQLSMALLINT BufferLength,
SQLSMALLINT *StringLengthPtr,
SQLLEN *NumericAttributePtr);
参数
表7-18 SQLColAttribute参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄。 |
ColumnNumber | 要检索字段的列号,起始为1,依次递增。 |
FieldIdentifier | IRD中ColumnNumber行的字段。 |
CharacterAttributePtr | 输出参数:一个缓冲区指针,返回FieldIdentifier字段值。 |
BufferLength |
- 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个字符串或二进制缓冲区,则此参数为该缓冲区的长度。
- 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个整数,则会忽略该字段。 |
StringLengthPtr | 输出参数:缓冲区指针,存放*CharacterAttributePtr中字符类型数据的字节总数,对于非字符类型,忽略BufferLength的值。 |
NumericAttributePtr | 输出参数:指向一个整型缓冲区的指针,返回IRD中ColumnNumber行FieldIdentifier字段的值。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLColAttribute返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLConnect
功能描述
在驱动程序和数据源之间建立连接。连接上数据源之后,可以通过连接句柄访问到所有有关连接数据源的信息,包括程序运行状态、事务处理状态和错误信息。
原型
SQLRETURN SQLConnect(SQLHDBC ConnectionHandle,
SQLCHAR *ServerName,
SQLSMALLINT NameLength1,
SQLCHAR *UserName,
SQLSMALLINT NameLength2,
SQLCHAR *Authentication,
SQLSMALLINT NameLength3);
参数
表7-19 SQLConnect参数
关键字 | 参数说明 |
---|---|
ConnectionHandle | 连接句柄,通过SQLAllocHandle获得。 |
ServerName | 要连接数据源的名称。 |
NameLength1 | ServerName的长度。 |
UserName | 数据源中数据库用户名。 |
NameLength2 | UserName的长度。 |
Authentication | 数据源中数据库用户密码。 |
NameLength3 | Authentication的长度。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
注意事项
当调用SQLConnect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_DBC和ConnectionHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLDisconnect
功能描述
关闭一个与特定连接句柄相关的连接。
原型
SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle);
参数
表7-20 SQLDisconnect参数
关键字 | 参数说明 |
---|---|
ConnectionHandle | 连接句柄,通过SQLAllocHandle获得。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当调用SQLDisconnect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_DBC和ConnectionHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLExecDirect
功能描述
使用参数的当前值,执行一条准备好的语句。对于一次只执行一条SQL语句,SQLExecDirect是最快的执行方式。
原型
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,
SQLCHAR *StatementText,
SQLINTEGER TextLength);
参数
表7-21 SQLExecDirect参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄,通过SQLAllocHandle获得。 |
StatementText | 要执行的SQL语句。不支持一次执行多条语句。 |
TextLength | StatementText的长度。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_NEED_DATA:在执行SQL语句前没有提供足够的参数。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
SQL_NO_DATA:表示SQL语句不返回结果集。
注意事项
当调用SQLExecDirect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLExecute
功能描述
如果语句中存在参数标记的话,SQLExecute函数使用参数标记参数的当前值,执行一条准备好的SQL语句。
原型
SQLRETURN SQLExecute(SQLHSTMT StatementHandle);
参数
表7-22 SQLExecute参数
关键字 | 参数说明 |
---|---|
StatementHandle | 要执行语句的语句句柄。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_NEED_DATA:表示在执行SQL语句前没有提供足够的参数。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_NO_DATA:表示SQL语句不返回结果集。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
注意事项
当SQLExecute函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLFetch
功能描述
从结果集中取下一个行集的数据,并返回所有被绑定列的数据。
原型
SQLRETURN SQLFetch(SQLHSTMT StatementHandle);
参数
表7-23 SQLFetch参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄,通过SQLAllocHandle获得。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_NO_DATA:表示SQL语句不返回结果集。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
注意事项
当调用SQLFetch函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLFreeStmt
在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeStmt已被SQLFreeHandle代替。有关详细信息请参阅7.2.15SQLFreeHandle。
SQLFreeConnect
在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeConnect已被SQLFreeHandle代替。有关详细信息请参阅7.2.15SQLFreeHandle。
SQLFreeHandle
功能描述
释放与指定环境、连接、语句或描述符相关联的资源,它替代了ODBC 2.x函数SQLFreeEnv、SQLFreeConnect及SQLFreeStmt。
原型
SQLRETURN SQLFreeHandle(SQLSMALLINT HandleType,
SQLHANDLE Handle);
参数
表7-24 SQLFreeHandle参数
关键字 | 参数说明 |
---|---|
HandleType | SQLFreeHandle要释放的句柄类型。必须为下列值之一:
- SQL_HANDLE_ENV - SQL_HANDLE_DBC - SQL_HANDLE_STMT - SQL_HANDLE_DESC 如果HandleType不是这些值之一,SQLFreeHandle返回SQL_INVALID_HANDLE。 |
Handle | 要释放的句柄。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
如果SQLFreeHandle返回SQL_ERROR,句柄仍然有效。
示例
参见:7.2.23示例
SQLFreeEnv
在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeEnv已被SQLFreeHandle代替。有关详细信息请参阅7.2.15SQLFreeHandle。
SQLPrepare
功能描述
准备一个将要进行的SQL语句。
原型
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle,
SQLCHAR *StatementText,
SQLINTEGER TextLength);
参数
表7-25 SQLPrepare参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄。 |
StatementText | SQL文本串。 |
TextLength | StatementText的长度。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
注意事项
当SQLPrepare返回的值为SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数分别设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLGetData
功能描述
SQLGetData返回结果集中某一列的数据。可以多次调用它来部分地检索不定长度的数据。
原型
SQLRETURN SQLGetData(SQLHSTMT StatementHandle,
SQLUSMALLINT Col_or_Param_Num,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN *StrLen_or_IndPtr);
参数
表7-26 SQLGetData参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄,通过SQLAllocHandle获得。 |
Col_or_Param_Num | 要返回数据的列号。结果集的列按增序从1开始编号。书签列的列号为0。 |
TargetType | TargetValuePtr缓冲中的C数据类型的类型标识符。若TargetType为SQL_ARD_TYPE,驱动使用ARD中SQL_DESC_CONCISE_TYPE字段的类型标识符。若为SQL_C_DEFAULT,驱动根据源的SQL数据类型选择缺省的数据类型。 |
TargetValuePtr | 输出参数:指向返回数据所在缓冲区的指针。 |
BufferLength | TargetValuePtr所指向缓冲区的长度。 |
StrLen_or_IndPtr | 输出参数:指向缓冲区的指针,在此缓冲区中返回长度或标识符的值。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_NO_DATA:表示SQL语句不返回结果集。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
SQL_STILL_EXECUTING:表示语句正在执行。
注意事项
当调用SQLGetData函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用7.2.19SQLGetDiagRec函数,并将HandleType和Handle参数分别设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLGetDiagRec
功能描述
返回诊断记录的多个字段的当前值,其中诊断记录包含错误、警告及状态信息。
原型
SQLRETURN SQLGetDiagRec(SQLSMALLINT HandleType
SQLHANDLE Handle,
SQLSMALLINT RecNumber,
SQLCHAR *SQLState,
SQLINTEGER *NativeErrorPtr,
SQLCHAR *MessageText,
SQLSMALLINT BufferLength
SQLSMALLINT *TextLengthPtr);
参数
表7-27 SQLGetDiagRec参数
关键字 | 参数说明 |
---|---|
HandleType | 句柄类型标识符,它说明诊断所要求的句柄类型。必须为下列值之一:
- SQL_HANDLE_ENV - SQL_HANDLE_DBC - SQL_HANDLE_STMT - SQL_HANDLE_DESC |
Handle | 诊断数据结构的句柄,其类型由HandleType来指出。如果HandleType是SQL_HANDLE_ENV,Handle可以是共享的或非共享的环境句柄。 |
RecNumber | 指出应用从查找信息的状态记录。状态记录从1开始编号。 |
SQLState | 输出参数:指向缓冲区的指针,该缓冲区存储着有关RecNumber的五字符的SQLSTATE码。 |
NativeErrorPtr | 输出参数:指向缓冲区的指针,该缓冲区存储着本地的错误码。 |
MessageText | 指向缓冲区的指针,该缓冲区存储着诊断信息文本串。 |
BufferLength | MessageText的长度。 |
TextLengthPtr | 输出参数:指向缓冲区的指针,返回MessageText中的字节总数。如果返回字节数大于BufferLength,则MessageText中的诊断信息文本被截断成BufferLength减去NULL结尾字符的长度。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
SQLGetDiagRec不发布自己的诊断记录。它用下列返回值来报告它自己的执行结果:
SQL_SUCCESS:函数成功返回诊断信息。
SQL_SUCCESS_WITH_INFO:*MessageText太小以致不能容纳所请求的诊断信息。没有诊断记录生成。
SQL_INVALID_HANDLE:由HandType和Handle所指出的句柄是不合法句柄。
SQL_ERROR:RecNumber小于等于0或BufferLength小于0。
如果调用ODBC函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO,可调用SQLGetDiagRec返回诊断信息值SQLSTATE,SQLSTATE值的如下表。
表7-28 SQLSTATE值
SQLSATATE | 错误 | 描述 |
---|---|---|
HY000 | 一般错误 | 未定义特定的SQLSTATE所产生的一个错误。 |
HY001 | 内存分配错误 | 驱动程序不能分配所需要的内存来支持函数的执行或完成。 |
HY008 | 取消操作 | 调用SQLCancel取消执行语句后,依然在StatementHandle上调用函数。 |
HY010 | 函数系列错误 | 在为执行中的所有数据参数或列发送数据前就调用了执行函数。 |
HY013 | 内存管理错误 | 不能处理函数调用,可能由当前内存条件差引起。 |
HYT01 | 连接超时 | 数据源响应请求之前,连接超时。 |
IM001 | 驱动程序不支持此函数 | 调用了StatementHandle相关的驱动程序不支持的函数 |
示例
参见:7.2.23示例
SQLSetConnectAttr
功能描述
设置控制连接各方面的属性。
原型
SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
参数
表7-29 SQLSetConnectAttr参数
关键字 | 参数说明 |
---|---|
ConnectionHandle | 连接句柄。 |
Attribute | 设置属性。 |
ValuePtr | 指向对应Attribute的值。依赖于Attribute的值,ValuePtr是32位无符号整型值或指向以空结束的字符串。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。 |
StringLength | 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLSetConnectAttr的返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过借助SQL_HANDLE_DBC的HandleType和ConnectionHandle的Handle,调用7.2.19SQLGetDiagRec可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLSetEnvAttr
功能描述
设置控制环境各方面的属性。
原型
SQLRETURN SQLSetEnvAttr(SQLHENV EnvironmentHandle
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
参数
表7-30 SQLSetEnvAttr参数
关键字 | 参数说明 |
---|---|
EnvironmentHandle | 环境句柄。 |
Attribute | 需设置的环境属性,可为如下值:
- SQL_ATTR_ODBC_VERSION:指定ODBC版本。 - SQL_CONNECTION_POOLING:连接池属性。 - SQL_OUTPUT_NTS:指明驱动器返回字符串的形式。 |
ValuePtr | 指向对应Attribute的值。依赖于Attribute的值,ValuePtr可能是32位整型值,或为以空结束的字符串。 |
StringLength | 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLSetEnvAttr的返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过借助SQL_HANDLE_ENV的HandleType和EnvironmentHandle的Handle,调用7.2.19SQLGetDiagRec可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
SQLSetStmtAttr
功能描述
设置相关语句的属性。
原型
SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
参数
表7-31 SQLSetStmtAttr参数
关键字 | 参数说明 |
---|---|
StatementHandle | 语句句柄。 |
Attribute | 需设置的属性。 |
ValuePtr | 指向对应Attribute的值。依赖于Attribute的值,ValuePtr可能是32位无符号整型值,或指向以空结束的字符串,二进制缓冲区,或者驱动定义值。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。 |
StringLength | 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。 |
返回值
SQL_SUCCESS:表示调用正确。
SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。
SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。
SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。
注意事项
当SQLSetStmtAttr的返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过借助SQL_HANDLE_STMT的HandleType和StatementHandle的Handle,调用7.2.19SQLGetDiagRec可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。
示例
参见:7.2.23示例
示例
常用功能示例代码
// 此示例演示如何通过ODBC方式获取Vastbase中的数据。
// DBtest.c (compile with: libodbc.so)
#include <stdlib.h>
#include <stdio.h>
#include <sqlext.h>
#ifdef WIN32
#include <windows.h>
#endif
SQLHENV V_OD_Env; // Handle ODBC environment
SQLHSTMT V_OD_hstmt; // Handle statement
SQLHDBC V_OD_hdbc; // Handle connection
char typename[100];
SQLINTEGER value = 100;
SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
int main(int argc,char *argv[])
{
// 1. 申请环境句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle\n");
exit(0);
}
// 2. 设置环境属性(版本信息)
SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 3. 申请连接句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
// 4. 设置连接属性
SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
// 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
// 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "vastbase", SQL_NTS,
(SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d\n",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !\n");
// 6. 设置语句属性
SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
// 7. 申请语句句柄
SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
// 8. 直接执行SQL语句。
SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS);
// 9. 准备执行
SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS);
// 10. 绑定参数
SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
&value,0,NULL);
// 11. 执行准备好的语句
SQLExecute(V_OD_hstmt);
SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
// 12. 获取结果集某一列的属性
SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
printf("SQLColAtrribute %s\n",typename);
// 13. 绑定结果集
SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
(SQLLEN *)&V_OD_err);
// 14. 通过SQLFetch取结果集中数据
V_OD_erg=SQLFetch(V_OD_hstmt);
// 15. 通过SQLGetData获取并返回数据。
while(V_OD_erg != SQL_NO_DATA)
{
SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
printf("SQLGetData ----ID = %d\n",V_OD_id);
V_OD_erg=SQLFetch(V_OD_hstmt);
};
printf("Done !\n");
// 16. 断开数据源连接并释放句柄资源
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
return(0);
}
批量绑定示例代码
/**********************************************************************
* 请在数据源中打开UseBatchProtocol,同时指定数据库中参数support_batch_bind
* 为on
* CHECK_ERROR的作用是检查并打印错误信息。
* 此示例将与用户交互式获取DSN、模拟的数据量,忽略的数据量,并将最终数据入库到test_odbc_batch_insert中
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include "util.c"
void Exec(SQLHDBC hdbc, SQLCHAR* sql)
{
SQLRETURN retcode; // Return status
SQLHSTMT hstmt = SQL_NULL_HSTMT; // Statement handle
SQLCHAR loginfo[2048];
// Allocate Statement Handle
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
hstmt, SQL_HANDLE_STMT);
// Prepare Statement
retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS);
sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
// Execute Statement
retcode = SQLExecute(hstmt);
sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
// Free Handle
retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql);
CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
}
int main ()
{
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc = SQL_NULL_HDBC;
int batchCount = 1000;
SQLLEN rowsCount = 0;
int ignoreCount = 0;
SQLRETURN retcode;
SQLCHAR dsn[1024] = {'\0'};
SQLCHAR loginfo[2048];
// 交互获取数据源名称
getStr("Please input your DSN", (char*)dsn, sizeof(dsn), 'N');
// 交互获取批量绑定的数据量
getInt("batchCount", &batchCount, 'N', 1);
do
{
// 交互获取批量绑定的数据中,不要入库的数据量
getInt("ignoreCount", &ignoreCount, 'N', 1);
if (ignoreCount > batchCount)
{
printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount);
}
}while(ignoreCount > batchCount);
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)",
henv, SQL_HANDLE_ENV);
// Set ODBC Verion
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER*)SQL_OV_ODBC3, 0);
CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)",
henv, SQL_HANDLE_ENV);
// Allocate Connection
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
henv, SQL_HANDLE_DBC);
// Set Login Timeout
retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_LOGIN_TIMEOUT)",
hdbc, SQL_HANDLE_DBC);
// Set Auto Commit
retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)(1), 0);
CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT)",
hdbc, SQL_HANDLE_DBC);
// Connect to DSN
sprintf(loginfo, "SQLConnect(DSN:%s)", dsn);
retcode = SQLConnect(hdbc, (SQLCHAR*) dsn, SQL_NTS,
(SQLCHAR*) NULL, 0, NULL, 0);
CHECK_ERROR(retcode, loginfo, hdbc, SQL_HANDLE_DBC);
// init table info.
Exec(hdbc, "drop table if exists test_odbc_batch_insert");
Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))");
// 下面的代码根据用户输入的数据量,构造出将要入库的数据:
{
SQLRETURN retcode;
SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT;
int i;
SQLCHAR *sql = NULL;
SQLINTEGER *ids = NULL;
SQLCHAR *cols = NULL;
SQLLEN *bufLenIds = NULL;
SQLLEN *bufLenCols = NULL;
SQLUSMALLINT *operptr = NULL;
SQLUSMALLINT *statusptr = NULL;
SQLULEN process = 0;
// 这里是按列构造,每个字段的内存连续存放在一起。
ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount);
cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50);
// 这里是每个字段中,每一行数据的内存长度。
bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount);
bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount);
// 该行是否需要被处理,SQL_PARAM_IGNORE 或 SQL_PARAM_PROCEED
operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount);
memset(operptr, 0, sizeof(operptr[0]) * batchCount);
// 该行的处理结果。
// 注:由于数据库中处理方式是同一语句隶属同一事务中,所以如果出错,那么待处理数据都将是出错的,并不会部分入库。
statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount);
memset(statusptr, 88, sizeof(statusptr[0]) * batchCount);
if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds)
{
fprintf(stderr, "FAILED:\tmalloc data memory failed\n");
goto exit;
}
for (int i = 0; i < batchCount; i++)
{
ids[i] = i;
sprintf(cols + 50 * i, "column test value %d", i);
bufLenIds[i] = sizeof(ids[i]);
bufLenCols[i] = strlen(cols + 50 * i);
operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED;
}
// Allocate Statement Handle
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt);
CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
hstmtinesrt, SQL_HANDLE_STMT);
// Prepare Statement
sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)";
retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS);
sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount));
CHECK_ERROR(retcode, "SQLSetStmtAttr", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds);
CHECK_ERROR(retcode, "SQLBindParameter for id", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols);
CHECK_ERROR(retcode, "SQLBindParameter for cols", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process));
CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAMS_PROCESSED_PTR", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount);
CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_STATUS_PTR", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount);
CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_OPERATION_PTR", hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLExecute(hstmtinesrt);
sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
retcode = SQLRowCount(hstmtinesrt, &rowsCount);
CHECK_ERROR(retcode, "SQLRowCount execution", hstmtinesrt, SQL_HANDLE_STMT);
if (rowsCount != (batchCount - ignoreCount))
{
sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
}
else
{
sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT);
}
// check row number returned
if (rowsCount != process)
{
sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount);
CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
}
else
{
sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount);
CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT);
}
for (int i = 0; i < batchCount; i++)
{
if (i < ignoreCount)
{
if (statusptr[i] != SQL_PARAM_UNUSED)
{
sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]);
CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
}
}
else if (statusptr[i] != SQL_PARAM_SUCCESS)
{
sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]);
CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
}
}
retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt);
sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt");
CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
}
exit:
printf ("\nComplete.\n");
// Connection
if (hdbc != SQL_NULL_HDBC) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
// Environment
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}