unxiODBC编程(五)错误处理

ODBC的每个函数调用完毕都会返回一个SQLRETURN类型的返回码,这个类型其实是短整数(short int)类型,是一个16位的整数。返回值一共有下面几个值。

  1. SQL_SUCCESS,表示函数执行成功。

  2. SQL_SUCCESS_WITH_INFO,表示函数执行成功,但是返回了警告信息。比如连接数据库时返回密码即将过期信息。

  3. SQL_STILL_EXECUTING,表示调用函数时,前一个SQL语句还在执行。

  4. SQL_NEED_DATA,表示调用函数后,有动态数据需要提供。

  5. SQL_NO_DATA,表示调用函数后,没有数据返回。最典型的就是从结果集中Fetch数据时,取走最后一条数据后没有其他数据了,返回SQL_NO_DATA。

  6. SQL_ERROR,表示调用函数后,出现了错误。需要调用诊断函数获取错误信息。

  7. SQL_INVALID_HANDLE,表示调用函数时,传入了无效的句柄。

当调用的函数返回SQL_SUCCESS_WITH_INFO或SQL_ERROR时,可以调用SQLGetDiagRec()函数来返回错误信息,下面看看函数的原型和参数。

SQLRETURN SQLGetDiagRec(

SQLSMALLINT HandleType,

SQLHANDLE Handle,

SQLSMALLINT RecNumber,

SQLCHAR * SQLState,

SQLINTEGER * NativeErrorPtr,

SQLCHAR * MessageText,

SQLSMALLINT BufferLength,

SQLSMALLINT * TextLengthPtr);

HandleType是一个输入参数,是出错函数传入的句柄的类型。

Handle是一个输入参数,是出错函数传入的句柄。

RecNumber是一个输入参数,指示诊断记录的编号。记录从 1 开始编号。

SQLState是一个输出参数,返回状态码,该缓冲区将返回一个五个字符的 SQLSTATE 代码。

NativeErrorPtr是一个输出参数,返回错误码,该缓冲区将返回特定于数据源的本机错误代码。比如数据源是一个使用Oracle驱动程序的配置项,那么返回的就是Oracle的出错码。

MessageText是一个输出参数,指向返回诊断消息文本字符串的缓冲区的指针。用于存放出错信息。

BufferLength是一个输入参数,MessageText 缓冲区的长度(以字符为单位)。如果过小诊断函数会返回错误。

TextLengthPtr是一个输出参数,返回信息文本的总字符数。

看一个例子,连接数据库出错时,怎样处理错误。

SQLSMALLINT i;

SQLRETURN rc;

SQLINTEGER ecode;

SQLSMALLINT alen;

WCHAR msgtxt8192;

WCHAR stateSQL_SQLSTATE_SIZE+1;

rc = SQLConnect(dbch, (SQLCHAR *)ds_name, SQL_NTS, (SQLCHAR *)usrname, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS);

if ((rc == SQL_ERROR) || (rc == SQL_SUCCESS_WITH_INFO)) {

for (i=1; ; i++) {

rc = SQLGetDiagRec(SQL_HANDLE_DBC, dbch, i, (SQLCHAR *)state, &ecode,

(SQLCHAR *)msgtxt, (SQLSMALLINT)(sizeof(msgtxt) / sizeof(WCHAR)),

(SQLSMALLINT *)&alen);

if (rc == SQL_SUCCESS) {

fprintf(stderr, "ERROR: %s %d - %s\n", (char *)state, ecode, (char *)msgtxt);

} else if (rc == SQL_NO_DATA)

break;

else {

fprintf(stderr, "get diagnostic record error.\n");

break;

}

}

}

我们可以写一个函数来处理调用函数返回的结果。代码如下。

cpp 复制代码
/*
 * hndl  - 出错函数输入的句柄
 * htype - 出错函数输入的句柄类型
 * rc    - 出错函数的返回码
 */
SQLRETURN check_odbc_error(SQLHANDLE hndl, SQLSMALLINT htype, SQLRETURN rc)
{   
    SQLRETURN           ret;
    SQLSMALLINT         irec;
    SQLSMALLINT         alen; 
    SQLINTEGER          ecode; 
    WCHAR               msgtxt[8192]; 
    WCHAR               state[SQL_SQLSTATE_SIZE+1];


    switch (rc) {
        /* 函数返回成功,需要动态数据,没有数据了,直接返回原始码,不用处理错误 */
        case SQL_SUCCESS:
        case SQL_NEED_DATA:
        case SQL_NO_DATA:
            return (rc);

        /* 无效句柄 */
        case SQL_INVALID_HANDLE:
            fprintf(stderr, "Invalid handle!\n"):
            return (rc);

        /* 返回成功但有警告信息或者出错,处理错误记录 */
        case SQL_SUCCESS_WITH_INFO:
        case SQL_ERROR: 
            /* 从1开始取回每一条出错记录信息 */
            for (irec=1; ; irec++) {
                ret = SQLGetDiagRec(htype, hndl, irec, (SQLCHAR *)state, &ecode,
                    (SQLCHAR *)msgtxt, (SQLSMALLINT)(sizeof(msgtxt) / sizeof(WCHAR)),
                    (SQLSMALLINT *)&alen);

                if (ret == SQL_NO_DATA)
                    break;

                if (ret == SQL_SUCCESS) {
                    fprintf(stderr,"[%s] %d - %s\n",
                        (char *)state, ecode, (char *)msgtxt);
                } else {
                    fprintf(stderr, "Get diagnostic message error!\n");
                    break;
                }
            }

            return (rc);
    }

    return (0);
}

后面可以使用上面的函数来处理调用函数的返回码,简单实用,比如调用执行语句函数。

rc = SQLExecute(stmth);

check_odbc_error(stmth, SQL_HANDLE_STMT, rc);

如果你想看一些有关数据库的高技术含量的源代码和文档,请访问www.tomcoding.com网站。

相关推荐
NineData3 天前
DTCC 2026 预告|NineData CEO& 创始人叶正盛:面向 AI Agent 的数据库 DevOps 与数据复制实践
数据库·人工智能·数据库开发·devops·ninedata·数据库技术·dtcc
承渊政道4 天前
KES专业技能包发布:覆盖数据库开发、迁移与运维全流程
运维·数据库·gitee·数据库开发·金仓数据库
Tongzhi20265 天前
通芝科技无感考勤一体机:软硬一体,开箱即用
数据结构·数据库·科技·算法·均值算法·数据库开发
sugar__salt6 天前
MyBatis-Plus 从入门到实战:高效简化数据库开发的完整指南
数据库·spring boot·mybatis·数据库开发
Tongzhi202611 天前
考勤数据本地化存储:通芝科技无感考勤一体机的数据安全逻辑
大数据·数据结构·科技·均值算法·数据库开发·推荐算法
ClouGence11 天前
告别 Navicat!CloudDM:开源免费一站式数据库开发管理工具
数据库·sql·开源·数据库开发
long31616 天前
PostgreSQL 学习资料 · 入门 / 练习 / 精通 / 扩展
java·数据结构·数据库·spring boot·sql·postgresql·数据库开发
请为小H留灯1 个月前
2026最新!Mac安载MySQL 8.0 保姆级教程
数据库·mysql·macos·adb·数据库开发
石像鬼₧魂石1 个月前
【Y2Ksoft】贵阳枫叶控股ERP管理系统 —— 管业制造 · 全链路数字化 · 开箱即用
大数据·数据仓库·数据库开发·数据库架构
石像鬼₧魂石1 个月前
钢结构ERP管理系统 —— 玻璃拟态 · 单文件HTML(系统为开发测试虚拟数据)
大数据·数据仓库·制造·数据库开发·数据库架构