SQLSTATE与SQLCODE
SQLSTATE是由5个字符(包含数字或大写字母)组成的标准字符串,用于表达各类SQL语句的执行状态(含成功、警告与错误)。SQLSTATE采用分层结构设计:前两位字符表示总体分类(Class),后三位字符表示具体的子分类(Subclass)。例如,“00000”表示成功状态,“42P01”表示表或视图不存在。
SQLCODE是以整数形式反映SQL执行状态的数值,其取值约定如下:
- 0:表示命令成功执行。
- 正值(>0):表示执行成功但带有附加状态。SQL标准仅明确定义了+100(宏定义为ECPG_NOT_FOUND),表明上一条语句未对任何行产生影响或已到达游标末尾。
- 负值(<0):表示发生错误。SQL标准并未统一规定负值的具体含义,通常由特定的数据库系统或客户端接口自行定义。
- ecpg为嵌入式SQL新增加的SQLSTATE码有:22002、07001、07002、07006、07009、33000、42601、42804、42P03、YE000和YE001。其余SQLSTATE码沿用内核SQLSTATE码。
- 当SQLCODE为-400(ECPG_PGSQL)时,表示底层检测到了数据库服务端返回的内核错误,此时SQLSTATE直接透传内核相应错误的SQLSTATE。
| SQLCODE值 | SQLSTATE值 | 含义 |
|---|---|---|
| 0 (ECPG_NO_ERROR) | 00000 | 命令成功执行,无错误。 |
| 100 (ECPG_NOT_FOUND) | 02000 | 检索或处理的数据行数为零,或已到达游标末尾。 例如在循环中可通过检测该值判断游标是否遍历完毕: while (1)
{
EXEC SQL FETCH ... ;
if (sqlca.sqlcode == ECPG_NOT_FOUND)
break;
} 注:开发中通常直接声明EXEC SQL WHENEVER NOT FOUND DO BREAK;实现自动拦截 |
| -12 (ECPG_OUT_OF_MEMORY) | YE001 | 客户端虚拟内存已被耗尽(等价于系统定义-ENOMEM) |
| -200 (ECPG_UNSUPPORTED) | YE000 | 预处理器生成了当前客户端运行时库无法识别的指令。 |
| -201 (ECPG_TOO_MANY_ARGUMENTS) | 07001 / 07002 | 命令中指定的宿主变量数量超过该语句预期。 |
| -202 (ECPG_TOO_FEW_ARGUMENTS) | 07001 / 07002 | 表示命令指定的宿主变量数量低于该命令预期。 |
| -203 (ECPG_TOO_MANY_MATCHES) | 21000 | 查询返回了多行数据,但目标宿主变量仅支持存储单行结果。 |
| -204 (ECPG_INT_FORMAT) | 42804 | 宿主变量为int类型,但数据库字段值无法转换为整数(内部使用strtol()解析)。 |
| -205 (ECPG_UINT_FORMAT) | 42804 | 宿主变量为unsigned int类型,但数据库字段值无法转换为无符号整数(内部使用strtoul()解析)。 |
| -206 (ECPG_FLOAT_FORMAT) | 42804 | 宿主变量为float类型,但数据库字段值无法转换为浮点数(内部使用strtod()解析)。 |
| -207 (ECPG_NUMERIC_FORMAT) | 42804 | 宿主变量为numeric类型,但数据库字段值无法解析为合法numeric数值。 |
| -208 (ECPG_INTERVAL_FORMAT) | 42804 | 宿主变量为interval类型,但数据库字段值无法解析为合法时间间隔。 |
| -209 (ECPG_DATE_FORMAT) | 42804 | 宿主变量为date类型,但数据库字段值无法解析为合法日期。 |
| -210 (ECPG_TIMESTAMP_FORMAT) | 42804 | 宿主变量为timestamp类型,但数据库字段值无法解析为合法时间戳。 |
| -211 (ECPG_CONVERT_BOOL) | 42804 | 宿主变量为boolean类型,但数据库返回的数据既非't'也非'f' |
| -212 (ECPG_EMPTY) | YE000 | 发送给数据库服务器的语句是空值(通常在一个嵌入式SQL程序中不会发生,因此它可能指向一个内部错误)。 |
| -213 (ECPG_MISSING_INDICATOR) | 22002 | 返回了一个空值并且没有提供空值指示符。 |
| -214 (ECPG_NO_ARRAY) | 42804 | 在要求一个数组的地方使用了一个普通变量。 |
| -215 (ECPG_DATA_NOT_ARRAY) | 42804 | 在一个要求数组值的地方数据库返回了一个普通变量。 |
| -216 (ECPG_ARRAY_INSERT) | 42804 | 尝试插入数组中的值类型不匹配或非法。 |
| -220 (ECPG_NO_CONN) | 08003 | 尝试访问不存在的数据库连接。 |
| -221 (ECPG_NOT_CONN) | YE000 | 尝试访问一个存在的连接但是未被开启(内部错误)。 |
| -230 (ECPG_INVALID_STMT) | 26000 | 尝试执行尚未进行PREPARE预编译的语句。 |
| -239 (ECPG_INFORMIX_DUPLICATE_KEY) | 23505 | 重复键错误,违背唯一约束。 |
| -240 (ECPG_UNKNOWN_DESCRIPTOR) | 33000 | 未找到指定的SQL描述符(Descriptor),或尝试使用的语句尚未准备就绪。 |
| -241 (ECPG_INVALID_DESCRIPTOR_INDEX) | 07009 | 访问的描述符索引超出合法范围。 |
| -242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM) | YE000 | 请求了一个非法的描述符(内部错误)。 |
| -243 (ECPG_VAR_NOT_NUMERIC) | 07006 | 执行动态SQL期间,数据库返回了numeric数值,但宿主变量为非numeric类型。 |
| -244 (ECPG_VAR_NOT_CHAR) | 07006 | 执行动态SQL期间,数据库返回了非numeric值,但宿主变量为numeric类型。 |
| -284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE) | 21000 | 子查询的结果不是单一行。 |
| -400 (ECPG_PGSQL) | 透传内核代码 | 数据库服务端触发了错误,错误文本与SQLSTATE取自服务端原始响应。 |
| -401 (ECPG_TRANS) | 08007 | 数据库服务器通知无法开启、提交或回滚事务。 |
| -402 (ECPG_CONNECT) | 08001 | 无法建立数据库连接。 |
| -403 (ECPG_DUPLICATE_KEY) | 23505 | 重复键错误,违背唯一约束。 |
| -404 (ECPG_SUBSELECT_NOT_ONE) | 21000 | 子查询的结果不是单一行。 |
| -602 (ECPG_WARNING_UNKNOWN_PORTAL) | 34000 | 指定了一个非法的游标名。 |
| -603 (ECPG_WARNING_IN_TRANSACTION) | 25001 | 事务正在进行。 |
| -604 (ECPG_WARNING_NO_TRANSACTION) | 25P01 | 尝试提交或回滚事务,但当前无活动事务。 |
| -605 (ECPG_WARNING_PORTAL_EXISTS) | 42P03 | 尝试创建已存在的游标名称。 |