嵌入的 SQL 接口提供了一种简单的,但是也很全面的方法来处理 程序里的例外条件。的一种方法会在一定的条件发生的时候自动打印 一些信息。比如:
EXEC SQL WHENEVER sqlerror sqlprint;
或者
EXEC SQL WHENEVER not found sqlprint;
这个错误句柄在整个程序里面都有效。
注意: 这可不是EXEC SQL WHENEVER语句 用法的穷尽的例子。有关用法的更多例子可以在 SQL 手册里找到(比如, Groff 和 Weinberg 写的The LAN TIMES Guide to SQL)。
如果需要更强大的错误处理,那么嵌入的 SQL 接口提供了 一个 struct 和一个变量,名字叫 sqlca, 如下所述:
struct sqlca { char sqlcaid[8]; long sqlabc; long sqlcode; struct { int sqlerrml; char sqlerrmc[70]; } sqlerrm; char sqlerrp[8]; long sqlerrd[6]; /* 0: 空 */ /* 1: 如果适用,则时被处理行的 OID */ /* 2: 在 INSERT, UPDATE,或者 DELETE 语句中 */ /* 处理的行数 */ /* 3: 空 */ /* 4: 空 */ /* 5: 空 */ char sqlwarn[8]; /* 0: 如果至少还有一个是 'W',则设置为 'W' */ /* 1: 如果至少有一个字符串数值在存储到 */ /* 某个宿主变量时被截断了,则设置为'W' */ /* 2: 空 */ /* 3: 空 */ /* 4: 空 */ /* 5: 空 */ /* 6: 空 */ /* 7: 空 */ char sqlext[8]; } sqlca;
(许多空的数域可能在将来的版本中使用。)
如果没有发生错误,那么最后的 SQL 语句, sqlca.sqlcode 将会是 0(ECPG_NO_ERROR)。 如果 sqlca.sqlcode 小于零,那么这是一个严重的 错误,比如像数据库定义和查询不匹配等等。如果它大于零, 那么它是一个普通的错误,比如像表不包含要求的行等等。
sqlca.sqlerrm.sqlerrmc 将包含一个描述错误 的字串。这个字串以(发生错误的)源代码文件中的行数结束。
下面是可能发生的错误:
通常不应该发生。这表明你的内存耗尽了。
通常不应该发生。这表明预处理器生成了一些库不认识的东西。 可能你运行的预处理器和库的版本不兼容。
这意味着服务器 返回了比我们的匹配变量更多的参数. 可能你漏了几个 INTO :var1,:var2-列表里的宿主变量.
这意味着服务器 返回了比我们的对应宿主变量要少的参数. 可能你多输入了几个 INTO :var1,:var2-列表里的宿主变量.
这意味着查询返回了多个行,但你声明的变量不是数组. SELECT命令不是唯一的.
这意味着宿主变量是一个 int 类型而 PostgreSQL 数据库里的字段是另一种类型, 包含着一个不能转换成一个 int 类型的数值.库(函数)使用 strtol() 做此类转换.
这意味着宿主变量是一个 unsigned int (无符号整数)类型而 PostgreSQL 数据库里的字段是另外一种类型 并且包含一个不能转换成 unsigned int的数值.库(函数)使用 strtoul() 做这类转换.
这意味着宿主变量是一个 float (浮点)类型而 PostgreSQL 数据库里的字段是另外一种类型并且 包含一个不能转换成 float的数值.库(函数)使用 strtod() 做这类转换.
这意味着宿主变量是一个 bool (布尔)类型,而 PostgreSQL 数据库里的字段值既不是't'也不是'f'。
查询实际上是空的。 (通常在嵌入的 SQL 程序里不可能发生,因此它可能指向一个内部错误。)
收到了一个 NULL 返回但是没有提供 NULL 指示符变量。
是因为在一个需要数组的地方使用了一个普通变量.
数据库在一个需要数组数值的地方返回了一个普通变量.
程序试图访问一个不存在的联接。
程序试图访问一个存在的,但是没有打开的联接。
你试图使用的语句还没准备好。
没有找到你声明的描述符.你试图使用的语句没有准备好.
声明的描述符索引超出了范围.
没有找到你声明的描述符.你试图使用的语句没有准备好.
数据库返回了一个数字数值,而该变量不是数字数值.
数据库返回了一个非数字数值,但该变量是数字类型.
某种 PostgreSQL 错误。该消息包含来自 PostgreSQL 后端的信息。
PostgreSQL 给我们的信号,告诉我们无法开始,提交或者回卷该事务。
与数据库的联接无法工作。
这是一个"正常的"错误, 告诉你你正在查询的东西找不到或者我们已经到了游标的结尾。