错误处理¶
ACI的错误处理包含两部分内容,一部分是有数据库执行报错返回的错误信息,一部分是有ACI处理层返回的错误信息。
返回值¶
ACI的所有接口调用,返回值大约有以下几种:
| 宏定义 | 值 | 意义 |
|---|---|---|
| ACI_SUCCESS | 0 | 执行接口返回正确 |
| ACI_SUCCESS_WITH_INFO | 1 | 执行正确,但会警告信息,比如数据查询,绑定变量大小小于实际数据长度时,获取数据被截断,会返回1并有警告信息 |
| ACI_ERROR | -1 | 执行出错,需要开发者获取重新,调整程序后重新执行 |
| ACI_INVALID_HANDLE | -2 | 代表无效的句柄或者参数值,无效的句柄主要是传入了一些NULL的句柄给调用接口,或者传入的句柄不是期望的句柄类型 无效参数值:比如接口要求传入>=1的值,但开发者给了一个小于1的值,也会返回ACI_INVALID_HANDLE |
| ACI_NO_DATA | 100 | 主要是针对查询语句,但我们获取结果集时如果没有数据,则返回ACI_NO_DATA |
| ACI_NEED_DATA | 99 | 主要是针对分段、或者动态绑定,当我们执行语句时,需要绑定或定义的数据并没有完成,则会返回ACI_NEED_DATA |
错误信息获取¶
ACI提供ACI_HTYPE_ERROR类型的句柄ACIError*,并通过 ACIErrorGet 函数获取其中的错误,对于ACIError句柄,里面的错误信息是一个队列,默认获取最新的一个,即第一个:
text errbuf[512];
sb4 errcode;
ACIErrorGet( err, (ub4) 1, (text *) NULL, &errcode,
errbuf, (ub4) sizeof(errbuf), (ub4) ACI_HTYPE_ERROR);
如果想获取队列中第二个错误信息,则可以将 ACIErrorGet 的第二个参数实则为2即可。
错误信息编码¶
一些错误代码只代表ACI处理逻辑中的错误信息,数据库服务端返回错误信息不在此范围:
| sqlstate | sqlcode | 错误信息 |
|---|---|---|
| 00000 | 0 | 未知错误 |
| 00001 | 0 | 保留不使用 |
| 00002 | 3113 | 连接已经断开 |
| 00003 | -1000 | 不支持的数据类型 |
| 00004 | -1001 | 数据类型转换出错 |
| 00005 | -1002 | 内存分配错误 |
| 00006 | 24315 | 非法的属性类型 |
| 00007 | 24391 | 提取操作无效 |
| 00008 | 3114 | 无法建立连接 |
| 00009 | 24338 | 未执行语句句柄 |
| 000010 | 1007 | 变量不在选择列表中 |
| 000011 | 24374 | 在读取或执行并读取之前没有完成定义 |
| 000012 | 1036 | 非法的变量名/编号 |
| 000013 | 24337 | 未准备语句句柄 |
| 000014 | 1008 | 并非所有变量都已绑定 |
| 000015 | 24373 | 为语句指定的长度无效 |
| 000016 | 1012 | 没有登录 |
| 000017 | 24333 | 零迭代计数 |
| 000018 | 1480 | STR 绑定值的结尾 Null 字符缺失 |
| 000019 | 1406 | 提取的列值被截断 |
| 000020 | 24309 | 已连接至服务器 |
| 000021 | 24310 | 为空的连接字符串指定的长度 |
| 000022 | 12163 | 连接描述符太长 |
| 000023 | 24300 | 模式值错误 |
| 000024 | 12154 | 无法解析指定的连接标识符 |
| 000025 | -2 | 属性输出的缓冲区为NULL |
| 000026 | 24314 | 未初始化服务句柄 |
| 000027 | 24327 | 在证明一个用户之前,需要明确的连接 |
| 000028 | 24313 | 用户已获得证明 |
| 000029 | 1722 | 无效数字 |
| 000030 | 1405 | 提取的列值为 NULL |
| 000031 | 4043 | 对象不存在 |
| 000032 | 1009 | 必须的参数缺失 |
| 000033 | 2005 | 隐含 (-1) 长度对数据类型的定义和绑定无效 |
| 000034 | 1017 | 用户名/口令无效; 登录被拒绝 |
| 000035 | -1003 | 无法获取系统时间 |
| 000036 | -1004 | 日期值不合法 |
| 000037 | 21560 | 参数为空,无效或超出范围 |
| 000038 | 1841 | (完整) 年份值必须介于 -4713 和 +9999 之间,且不为 0 |
| 000039 | 1846 | 周中的日无效 |
| 000040 | 1801 | 日期格式对于内部缓冲区过长 |
| 000041 | 1877 | 内部缓冲区的字符串太长 |
| 000042 | 24316 | 此位置没有描述符 |
| 000043 | 3114 | 未连接到神通数据库 |
| 000044 | 24316 | 非法的句柄类型 |
| 000045 | 1005 | 给出空口令; 登录被拒绝 |
| 000046 | 22056 | 数值 [%s] 被零除 |
| 000047 | 22060 | 参数[2]是一个无效的或者未初始化的数值 |
| 000048 | 22060 | 参数[3]是一个无效的或者未初始化的数值 |
| 000049 | 22060 | 浮点数溢出 |
| 000050 | 22060 | 除法运算结果被截断 |
| 000051 | 0 | Fetch all时,行数超过内部允许的最大值 |
| 000052 | 0 | 浮点数精度过大,请采用字符串协议传输 |
| 000053 | 22926 | 指定的 trim 长度大于当前的 LOB 值长度 |
| 000054 | 22275 | 指定的 LOB 定位符无效 |
| 000055 | 24801 | 在 ACI lob 函数中非法的参数值 |
| 000056 | 24392 | 没有与服务器句柄相关的连接池 |
| 000057 | 24399 | 指定的连接数无效 |
| 000058 | 24404 | 连接池不存在 |
| 000059 | 24421 | ACISessionRelease 不能用于释放此会话 |
| 000060 | 24329 | 无效的字符集标识 |
| 000061 | 1870 | 间隔或日期时间不是相互可比较的 |
| 000062 | 932 | 数据类型不一致 |
| 000063 | 1873 | 间隔的前导精度太小 |
| 000064 | 1878 | 在日期时间或间隔没有找到指定的字段 |
| 000065 | 1875 | 时区分钟必须在 -59 和 59 之间 |
| 000066 | 1867 | 间隔无效 |
| 000067 | 1882 | 未找到时区 |
| 000068 | 1874 | 时区小时必须在 -12 和 14 之间 |
| 000069 | 1857 | 无效的时区 |
| 000070 | 24805 | LOB 类型不匹配 |
| 000071 | 22994 | 源偏移量超出源 LOB 的结尾 |
| 000072 | 24807 | LOB 格式不匹配 |
| 000073 | 22925 | 操作将超出 LOB 值允许的最大大小 |
| 000074 | 22993 | 指定的输入总数大于实际的来源总数 |
| 000075 | 22994 | 源偏移量超出源 LOB 的结尾 |
| 000076 | 22289 | 无法在未打开的文件或 LOB 上执行LOADFROMFILE操作 |
| 000077 | 24811 | 提供写入的数据少于指定的数据 |
| 000078 | 24810 | 正在尝试写入多于指定的数据 |
| 000079 | 24854 | 提供的片段信息无效 |
| 000080 | 22280 | 没有更多的缓冲区可用于此操作 |
| 000081 | 22279 | 在启用LOB缓冲时,无法执行此操作 |
| 000082 | 21779 | 持续时间不活动 |
| 000083 | 0 | 大容量导入句柄需初始化 |
| 000084 | 24452 | 不支持超过SB4MAXVAL的数据 |
| 000085 | 24434 | 在 ACIStmtPrepare2 之前调用了 ACIStmtRelease |
| 000086 | 1458 | 内部变量字符串长度无效 |
| 000087 | 1459 | 变量字符串长度无效 |
| 000088 | 24432 | 返回的语句没有标记 |
| 000089 | 1741 | 非法的零长度标识符 |
| 000090 | 972 | 标识符过长 |
| 000091 | 0 | 数据字符编码转换失败,确保输入有效的字符数据 |
| 000092 | 24422 | 在尝试销毁会话池时出现错误 |
| 000093 | 24416 | 会话池不存在 |
| 000094 | 24413 | 指定的会话数无效 |
| 000095 | 24484 | 创建池后不允许设置验证句柄 |
| 000096 | 00096 | 会话池大小超出了最大限制 |
| 000097 | 3123 | 操作将阻塞 |
| 000098 | 1453 | SET TRANSACTION 必须是第一个交易语句 |
| 000099 | 0 | 导入句柄没有设置列的值 |
| 000100 | 0 | 导入句柄没有设置行结束标志 |
| 000101 | 0 | 当前导入节点信息发生变更,可能是切主或者reblance导致 |
| 000102 | 0 | 绑定的列数少于所要导入列的个数 |
| 000103 | 0 | 指定的偏移或者获取行数无效 |
| 000104 | 0 | 指定的缓存无效 |
| 000105 | 0 | 列数超过所要导入列的个数 |
| 000106 | 0 | 不支持的客户端字符集 |
| 000107 | 0 | 设置keepalive功能出错 |
| 000108 | 0 | 获取服务端字符集出错 |
| 000109 | 0 | socket等待超时 |
| 000110 | 0 | 该表中没有找到主键 |
| 000111 | 0 | BFILE必须是只读模式 |
| 000112 | 0 | 将数据发送给服务端出错(Import_server) |
| 000113 | 0 | 偏移位置大于Rowid总行数 |
| 000114 | 0 | 无法创建MPP加载节点网络连接 |
| 000115 | 0 | 往MPP节点加载数据出错 |
| 000116 | 0 | MPP加载节点信息已变更 |
| 000117 | 24345 | 出现截断或空读取错误 |
| 000118 | 24349 | 数组 DML 行数不可用 |
| 000119 | 28714 | 只能为 INSERT, UPDATE, DELETE 或 MERGE 语句指定 ACI_BATCH_ERRORS 或 ACI_RETURN_ROW_COUNT_ARRAY 模式 |
| 000120 | 24423 | 无法设置 ROWID 属性 - ACI_ATTR_FETCH_ROWID |
| 000121 | 24424 | 在位置 0 处进行定义的尝试无效 |
| 000122 | 21301 | 没有按对象模式进行初始化 |
| 000123 | 21610 | 内存大小 [5] 无效 |
| 000124 | 21614 | handle和duration不匹配 |
| 000125 | 24960 | 属性 %s 的长度大于最大允许长度 %s |
| 000126 | 24384 | 应用程序上下文大小未初始化 |
| 000127 | 24385 | 应用程序上下文大小或索引无效 |
| 000128 | 1017 | 用户名/口令无效; 登录被拒绝 |
| 000129 | 24804 | 进行另一个 ACI LOB 读/写流时调用了 Lob 读/写功能 |
| 000130 | 0 | 未知属性 %s |
| 000131 | 0 | 指定路径下没有对应的SSL证书文件 |
| 000132 | 0 | SSL证书与SOCKET绑定失败 |
| 000133 | 0 | SSL证书验证失败 |
英文错误信息¶
ACI默认支持是中文错误信息,如果需要支持英文错误信息,有两种方式可以设置:
- 设置ACI的运行配置文件(sqlnet.aci),将errorinfo_language设置为false,但需要遵循参数配置文件的使用规则才能生效;
- 通过
ACIAttrSet接口设置环境句柄属性:
sb4 chinese_errorinfo = FALSE;
err = ACIAttrSet ((void *) env, ACI_HTYPE_ENV, (void *) chinese_errorinfo,
sizeof(chinese_errorinfo), ACI_ATTR_CHINESE_ERRORINFO, (ACIError *) err);
注解
数据库服务端返回的错误信息不受控制,数据库服务端的中英文信息切换,只能在数据库安装时选择,需要特别注意!