为了更强大的错误处理,嵌入式 SQL 接口提供了一个名为sqlca(SQL 通讯区域)的全局变量,它具有下面的结构:struct
{
char sqlcaid[8];
long sqlabc;
long sqlcode;
struct
{
int sqlerrml;
char sqlerrmc[SQLERRMC_LEN];
} sqlerrm;
char sqlerrp[8];
long sqlerrd[6];
char sqlwarn[8];
char sqlstate[5];
} sqlca;
(在一个多线程程序中,每一个线程会自动得到它自己的sqlca副本。这和对于标准 C 全局变量errno的处理相似。)
sqlca覆盖了警告和错误。如果执行一个语句时发生了多个警告或错误,那么sqlca将只包含关于最后一个的信息。
如果在上一个SQL语句中没有产生错误,sqlca.sqlcode将为 0 并且sqlca.sqlstate将为"00000"。如果发生一个警告或错误,则sqlca.sqlcode将为负并且sqlca.sqlstate将不为"00000"。一个正的sqlca.sqlcode表示一种无害的情况,例如上一个查询返回零行。sqlcode和sqlstate是两种不同的错误代码模式,详见下文。
如果上一个 SQL 语句成功,那么sqlca.sqlerrd[1]包含被处理行的 OID (如果可用),并且sqlca.sqlerrd[2]包含被处理或被返回的行数(如果适用于该命令)。
在发生一个错误或警告的情况下,sqlca.sqlerrm.sqlerrmc将包含一个描述该错误的字符串。域sqlca.sqlerrm.sqlerrml包含存储在sqlca.sqlerrm.sqlerrmc中错误消息的长度(strlen()的结果,对于一个 C 程序员来说并不感兴趣)。注意一些消息可能太长不能适应定长的sqlerrmc数组,它们将被截断。
在发生一个警告的情况下,sqlca.sqlwarn[2]被设置为W(在所有其他情况中,它被设置为不同于W的东西)。如果sqlca.sqlwarn[1]被设置为W,那么一个值被存储在一个主变量中时会被截断。如果任意其他元素被设置为指示一个警告,sqlca.sqlwarn[0]会被设置为W。
域sqlcaid、
sqlcabc、
sqlerrp以及
sqlerrd的剩余元素还有
sqlwarn当前不包含有用的信息。
SQL 标准中没有定义sqlca结构,但是在一些其他的 SQL 数据系统中都有实现。在核心上这些定义都想死,但是如果你想要编写可移植的应用,那么你应该仔细研究不同的实现。
这里有一个整合使用WHENEVER和sqlca的例子,当一个错误发生时打印出sqlca的内容。在安装一个更"用户友好"的错误处理器之前,这可能对调试或开发原型应用有用。EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
void
print_sqlca()
{
fprintf(stderr, "==== sqlca ====\n");
fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2],
sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5],
sqlca.sqlwarn[6], sqlca.sqlwarn[7]);
fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
fprintf(stderr, "===============\n");
}
结果看起来像(这里的错误是一个拼写错误的表名):==== sqlca ====
sqlcode: -400
sqlerrm.sqlerrml: 49
sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
sqlerrd: 0 0 0 0 0 0
sqlwarn: 0 0 0 0 0 0 0 0
sqlstate: 42P01
===============