更新时间:2026-10-21 GMT+08:00
sqlca
sqlca(SQL Communication Area,SQL通信区)是嵌入式SQL接口提供的全局结构体变量,用于保存当前数据库语句执行后的状态、告警与错误诊断信息。在多线程环境下,系统会自动为每个线程维护一份独立的sqlca副本以保证线程安全。若单条SQL语句在执行期间触发多个告警或错误,sqlca仅保留最后一条产生的异常信息。
sqlca数据结构如下:
struct
{
char sqlcaid[8]; /* 固定标识符字符串 "SQLCA " */
long sqlabc; /* sqlca结构体本身的内存字节大小 */
long sqlcode; /* 错误状态码:0表示成功,<0表示错误,100表示未查到数据(NOT FOUND) */
struct
{
int sqlerrml; /* 错误消息文本的实际长度 strlen() */
char sqlerrmc[SQLERRMC_LEN]; /* 错误描述字符串(以\0结尾,超长会被截断) */
} sqlerrm;
char sqlerrp[8]; /* 系统保留字段 */
long sqlerrd[6]; /* 状态诊断信息数组:sqlerrd[1]存储处理行的OID,sqlerrd[2]存储受影响/返回的数据行数 */
char sqlwarn[8]; /* 告警标志位数组:产生告警时sqlwarn[0]与sqlwarn[2]会被置为'W' */
char sqlstate[5]; /* 5字节标准SQLSTATE状态码(如"00000"表示成功) */
} sqlca; 核心字段功能与诊断规则:
- sqlcode与sqlstate:执行成功时,sqlcode为0且sqlstate为"00000";执行失败时,sqlcode为负数,sqlstate会返回符合SQL标准的5字节字符代码(例如"42P01"表示表或视图不存在)。具体的代码映射关系请参见SQLSTATE与SQLCODE。
- sqlerrm:包含sqlerrmc(错误消息文本)与sqlerrml(字符串实际长度)。由于sqlerrmc数组在内存中预分配的容量固定为SQLERRMC_LEN,需要注意的是,部分较长的错误消息可能会被截断。
- sqlerrd:sqlerrd[1]在数据插入或更新成功时记录对应行对象的OID;sqlerrd[2]记录当前SQL语句实际匹配、提取或修改的数据行数(如UPDATE修改的行数或SELECT查出的行数)。
- sqlwarn:当出现告警信息时,系统会将sqlwarn[2]元素设置为字符'W'。sqlcaid、sqlabc、sqlerrp及sqlwarn的其余数组元素由系统内部保留使用。
在实际开发中,通常将EXEC SQL WHENEVER自动拦截指令与sqlca数据结构结合使用,实现异常的集中打印与分析。
示例如下,需要提前创建testdb:
#include <stdio.h>
#include <stdlib.h>
#include <sqlca.h>
/*错误处理回调函数:从全局sqlca结构体中提取诊断明细*/
void print_sqlca(void)
{
fprintf(stderr, "==== sqlca 诊断信息 ====\n");
fprintf(stderr, "sqlcode : %ld\n", sqlca.sqlcode);
fprintf(stderr, "sqlstate : %.5s\n", sqlca.sqlstate);
fprintf(stderr, "sqlerrm : %s (len=%d)\n", sqlca.sqlerrm.sqlerrmc, sqlca.sqlerrm.sqlerrml);
fprintf(stderr, "sqlerrd2 : %ld (affected rows)\n", sqlca.sqlerrd[2]);
fprintf(stderr, "========================\n");
}
int main(void)
{
/* 声明当发生SQL错误时自动调用print_sqlca函数 */
EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
EXEC SQL CONNECT TO testdb;
/* 故意执行一条查询不存在表名的语句以触发错误 */
EXEC SQL SELECT * FROM pg_databasep;
EXEC SQL DISCONNECT ALL;
return 0;
} 运行结果如下(此处是一个拼写表名错误):
==== sqlca 诊断信息 ==== sqlcode : -400 sqlstate : 42P01 sqlerrm : relation "pg_databasep" does not exist on line 38 (len=49) sqlerrd2 : 0 (affected rows) ========================
父主题: 错误处理