返回首页

gbase数据、南大通用产品文档:GBase8s使用 sqlca 结构进行异常处理

更新日期:2024年09月11日

另一种获取诊断信息的方法是通过 SQL 通信区域。当执行 SQL 语句时,数据库服
务器字段返回名为 sqlca 的 C 结构中语句的成功或失败。
要获取异常信息,您的 GBase 8s ESQL/C 程序可以访问 sqlca 结构或 SQLCODE
变量,如下所示:
sqlca 结构。可以使用 C 结构获取附加的异常信息。还可以获取与性能相关的信息或
处理的数据的性质。对于某些语句,sqlca 结构包含警告。
SQLCODE 变量。 可以获取最近执行 SQL 语句的状态代码。SQLCODE 包含特定

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 298 -
于 GBase 8s 的错误代码,其从 sqlca.sqlcode 字段复制。
重要: GBase 8s ESQL/C 支持之前版本的 sqlca 结构。但是,建议新的应用程序使
用具有 GET DIAGNOSTICS 语句的 SQLSTATE 变量执行异常检查。
该方法符合 X/Open
和 ANSI SQL 标准,并支持多个异常。
之后的三个章节介绍了如何使用 SQLCODE 变量和 sqlca 结构执行异常处理。
本节
包含以下主题:
了解 sqlca 结构
使用 SQLCODE 变量获取错误代码
使用 sqlca 结构检查不同种类的异常
sqlca 结构的字段
sqlca 结构在 sqlca.h 头文件中定义。GBase 8s ESQL/C 预处理器自动在 GBase 8s
ESQL/C 程序中包含 sqlca.h 头文件。
下表描述了 sqlca 结构的字段。
表 1. sqlca 结构的字段
字段
类型

值描述
sqlcode
int4
0
表示成功。


>=0, <
100
DESCRIBE 语句之后,表
示所描述的 SQL 的类型


100
成功查询之后不返回任何
行,表示 NOT FOUND 条件。
在 INSERT INTO/SELECT 、
UPDATE 、DELETE 或
SELECT... INTO TEMP 语句无
法访问任何行之后,NOT
FOUND 也可能发生早符合
ANSI 的数据库中。


<0
错误代码。
sqlerrm
character (72) 或
character (600)

使用有关 GBase 8s 数据
库服务器时,此字段长度为 72
个字符,并包含错误消息参数。
此参数用于替换实际错误消息
中的 %s 令牌。如果错误消息

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 299 -
不需要参数,则此字段为空。
sqlerrp
character (8)

仅限内部使用。
sqlerrd
6 int4s 的数组
[0]
在 SELECT 、
UPDATE 、
INSERT 或 DELETE 语句成
功的 PREPARE 语句之后,或
在打开选择游标之后,
此字段包
含估计的受影响的行数。


[1]
当 SQLCODE 包含错误
代码时,
此字段包含零或其它错
误代码,
称为 ISAM 错误代码,
用于说明主错误的原因。
在成功插入一行后,此字
段不合适为此行生成的任何
SERIAL 值。


[2]
成功插入、更改或删除多
行后,此字段包含已处理的行
数。
在以错误结束插入、更改
或删除多行后,
此字段包含在检
测到错误之前已成功处理的行
数。


[3]
SELECT 、UPDATE 、
INSERT 或 DELETE 语句的
PREPARE 语句成功之后,
或者
打开选择游标之后,
此字段包含
磁盘访问和处理的总行的估计
加权和。


[4]
PREPARE 、EXECUTE
IMMEDIATE 、DECLARE 或
静态 SQL 语句中出现错误之
后,
此字段包含检测到错误的语
句文本中的偏移量。


[5]
在成功获取选择的行后,
或 insert 、
update 或 delete 操

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 300 -
作成功后,
此字段包含处理的最
后一行的 rowid(物理地址)。
该 rowid 值是否对应于数据库
服务器返回给用户的行,
取决于
数据库服务器如何处理查询,

别是 SELECT 语句。

表 2. 当打开数据库时 sqlca 结构的字段
字段



值描述
sqlwarn
8
字符的
数组
sqlwarn0
当其它警告字段设置为 W 时,此
字段设置为 W 。如果为空;不需要检
查其它字段。


sqlwarn1
当现在打开的数据库使用事务日
志时,设置为 W。


sqlwarn2
当现在打开的数据库是符合 ANSI
的时,设置为 W 。


sqlwarn3
设置为 W。


sqlwarn4
当数据库以 DECIMAL 格式存储
FLOAT 数据类型时,则设置为 W(当
主机系统缺少对 FLOAT 数据类型的
支持时)。


sqlwarn5
保留。


sqlwarn6
当应用程序连接到以辅助模式运
行的数据库服务器时,
设置为 。
数据库
服务器是数据复制对中的辅助服务器
(数据库服务器仅对读操作可用)。


sqlwarn7
Set to W 当客户端 DB_LOCALE
与数据库语言环境不匹配时,设置为
W。


GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 301 -
表 3. 所有其它操作的 sqlca 结构的字段:
字段



值描述
sqlwarn
8
字符的
数组
sqlwarn0
当其它警告字段设置为 W 时,设
置为 W 。如果为空,则不需检查
sqlwarn 中的其它字段。


sqlwarn1
如果使用在 FETCH 或
SELECT...INTO 语句将列值获取到主
机变量时,列值被截断,则设置为 W。
在 REVOKE ALL 语句中,,当所有七
个表级别特权都未被撤销时,设置为
W。


sqlwarn2
当 FETCH 或 SELECT 语句返回
聚集函数
(SUM 、
AVG 、
MIN 、
MAX)
的值的为空时,设置为 W。


sqlwarn3
在 SELECT...INTO 、
FETCH...INTO 或 EXECUTE...INTO
语句中,当选择列表中的项数与接收它
们的 INTO 子句中的给出的主机变量
的数不一致时,
设置为 W 。
在 GRANT
ALL 语句中,
当所有七个表级别特权都
未被撤销时,设置为 W。


sqlwarn4
如果 DESCRIBE 语句之后的预备
的语句包含不带 WHERE 子句的
DELETE 语句或 UPDATE 语句,则设
置为 W。


sqlwarn5
在执行不使用 ANSI 标准 SQL
语法的语句(设置了 DBANSIWARN
环境变量)后设置为 W。


sqlwarn6
在查询处理期间(DATASKIP 功
能启用)跳过数据段(dbspace)时,设
置为 W 。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 302 -


sqlwarn7
保留。
SQLCODE 变量
SQLCODE 变量是 int4,指示 SQL 语句成功还是失败。
GBase 8s ESQL/C 头文件 sqlca.h 将 SQLCODE 声明为全局变量。因为 GBase 8s
ESQL/C 预处理器在 GBase 8s ESQL/C 程序中自动包含 sqlca.h,所以您不需要声明
SQLCODE。
当数据库服务器执行 SQL 语句时,数据库服务器字段更新 SQLCODE 变量,如下
所示:
数据库服务器在 sqlca 结构的 sqlcode 字段中存储异常值。
GBase 8s ESQL/C 将 sqlca.sqlcode 的值复制到全局 SQLCODE 变量。
提示: 为了可读性和简洁性。请在 GBase 8s ESQL/C 程序中使用 SQLCODE 代替
sqlca.sqlcode。
SQLCODE 值可以表示以下类型的异常:
SQLCODE = 0
成功
SQLCODE = 100
NOT FOUND 条件
SQLCODE < 0
运行错误
纯 C 模块中的 SQLCODE
要返回与 GBase 8s ESQL/C 模块中返回的 SQLCODE 状态变量相同的值,可以在
链接到 GBase 8s ESQL/C 程序的纯 C 模块
(具有 .c 扩展名的模块)
中使用 SQLCODE。
要在纯 C 模块中使用 SQLCODE,请将 SQLCODE 声明为外部变量,如下所示:
extern int4 SQLCODE;
SQLCODE 和 exit() 调用
要将错误代码返回给父进程,不要尝试使用 SQLCODE 值作为 exit() 系统调用的
参数。当 GBase 8s ESQL/C 将 exit() 的参数传递给父代时,它只会传递值的低八位。因为
SQLCODE 是一个四字节(s a flong)整数,所以 GBase 8s ESQL/C 返回到父进程的值
可能不是您期望的。
要在进程之间传递错误消息,请使用退出值作为发生某种联系的错误的指示。要获取
有关时间错误的信息,请使用临时文件,数据库表或某种形式的进程间通信。
DESCRIBE 语句之后的 SQLCODE
DESCRIBE 语句返回语句执行的准备好的语句的信息。它使用 PREPARE 语句以前

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 303 -
分配给动态 SQL 语句的语句 ID 进行操作。
成功执行 DESCRIBE 语句之后,
数据库服务器将 SQLCODE
(和 sqlca.sqlcode)
设置为非负数,它表示 DESCRIBE 已检查的 SQL 语句的类型。sqlstype.h 头文件为每个
返回值声明常量名称。
因为 DESCRIBE 语句使用的 SQLCODE 字段与其它任何语句不同,
所以您可能需
要修改异常处理流程以适应这种差异。
检查 sqlca 异常
SQL 语句执行后,sqlca 结构可以指示下表所示的四个可能的条件之一。
表 1. sqlca 结构返回的异常
异常条件
sqlca 值
成功
SQLCODE(和 sqlca.sqlcode)= 0
成功,但未找到行
SQLCODE(和 sqlca.sqlcode)= 100
成功,但生成警告
sqlca.sqlwarn.sqlwarn0 = 'W'
要指示特定警告:
sqlwarn1 至 sqlwarn7 其中之一在
sqlca.sqlwarn 结构中也被设置为 W
失败,生成运行错误
SQLCODE(和 sqlca.sqlcode)< 0
sqlca 中成功
当数据库服务器成功执行 SQL 语句时,
它将 SQLCODE
(sqlca.sqlcode)
设置为 0。
数据库服务器可能还会在成功执行 SQL 语句之后在 sqlca 中设置以下一个或多个选项字
段:
在 SELECT 、INSERT 、DELETE 或 UPDATE 的 PREPARE 之后:
sqlca.sqlerrd[0] 表示估计受影响的行数。
sqlca.sqlerrd[3] 包含磁盘访问和处理的总行的估计加权和。
INSERT 之后,sqlca.sqlerrd[1] 包含数据库服务器为 SERIAL 列生成的值。
SELECT 、INSERT 、DELETE 或 UPDATE 之后:
sqlca.sqlerrd[2] 包含数据库服务器已处理的行数。
sqlca.sqlerrd[5] 包含最后处理的行的 rowid(物理地址)。该 rowid 值是否对应于
数据库服务器返回给用户的行,取决于数据库服务器如何处理查询。特别是对于 SELECT
语句。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 304 -
CONNECT 、
SET CONNECTION 、
DATABASE 、
CREATE DATABASE 或 START
DATABASE 之后,sqlca.sqlwarn.sqlwarn0 字段设置为 W,sqlca.sqlwarn 的其它字段提供
有关数据库和连接的信息。
SQLCODE 中 NOT FOUND
当 SELECT 或 FETCH 语句遇到 NOT FOUND (或 END OF DATA)时,数据库
服务器将 SQLCODE
(sqlca.sqlcode)
设置为 100。
下表列出了导致 SQL 语句发生 NOT
FOUND 的条件。
表 1. 当 SQL 语句未返回任何行时设置的 SQLCODE 值
SQL 语句生成指示的 SQLCODE 结果
符合 ANSI 的数
据库的结果
不符合 ANSI 的
数据库的结果
FETCH 语句:最后一个排序行已经被返回
(达到数据的末尾)。
100
100
SELECT 语句:
没有行符合 SELECT 条件。

100
100
DELETE 和 DELETE...WHERE 语句
(不是
多语句的 PREPARE 的部分):没有行符合
DELETE 条件。
100
0
INSERT INTO tablename SELECT 语句(不
是多语句的 PREPARE 的一部分):没有行符合
SELECT 条件。
100
0
SELECT... INTO TEMP 语句(不是多语句
的 PREPARE 的一部分)

没有行符合 SELECT
条件。
100
0
UPDATE 和 UPDATE...WHERE 替换(不
是多语句的 PREPARE 的一部分):没有行符合
UPDATE 条件。
100
0
表 1显示,在某些情况下,NOT FOUND 条件生成的值取决于数据库是否符合 ANSI
标准。
在下列示例中,INSERT 语句将订单数量大于 10,000 的库存项插入到 hot_items 表
中。如果没有任何项目的订单数量很大,则语句的 SELECT 部分无法插入任何行。数据库
服务器在符合 ANSI 的数据库中返回 100 ,在不符合 ANSI 的数据库中返回 0。
EXEC SQL insert into hot_items
select distinct stock.stock_num,
stock.manu_code,description

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 305 -
from items, stock
where stock.stock_num = items.stock_num
and stock.manu_code = items.manu_code
and quantity > 10000;
为了可读性,
请使用 END OF DATA 值为 100 的常量 SQLNOTFOUND 值。
sqlca.h
头文件定义 SQLNOTFOUND 常量。
以下比较检查 NOT FOUND 和 END OF DATA 条件:

if(SQLCODE == SQLNOTFOUND)
sqlca.sqlwarn 中的警告
当数据库服务器成功执行 SQL 语句,但遇到警告条件时,它将更新 sqlca.sqlwarn
结构中的以下两个字段:
将 sqlca.sqlwarn.sqlwarn0 字段设置为字母 W。
将 sqlwarn 结构(sqlwarn1 到 sqlwarn7)中的其中一个字段设置为字母 W,来指示
特定的警告条件。
这些警告都特定于 GBase 8s。
表 1包含可在 sqlca.sqlwarn 结构的字段中发生的两组
警告条件。表 1中显示的第一组警告发生在数据库服务器打开数据库或建立连接之后。第
二组警告是因为其它 SQL 语句可能发生的情况。
要测试警告,请检查第一个警告字段(sqlwarn0)是否设置为 W。在您确定数据库服
务器生成警告后,可以检查 sqlca.sqlwarn 中其它字段的值以识别特定条件。例如,如果
要查找 CONNECT 语句打开的数据库,可以使用下图显示的代码:
图: CONNECT 语句后检查警告的代码片段
int trans_db, ansi_db, us_db = 0;


msg = "CONNECT stmt";
EXEC SQL connect to 'stores7';
if(SQLCODE < 0) /* < 0 is an error */
err_chk(msg);
if (sqlca.sqlwarn.sqlwarn0 == 'W')
{
if (sqlca.sqlwarn.sqlwarn1 == 'W' )
trans_db = 1;
if (sqlca.sqlwarn.sqlwarn2 == 'W' )
ansi_db = 1;
if (sqlca.sqlwarn.sqlwarn3 == 'W' )
us_db = 1;
}
SQLCODE 中的运行错误
当 SQL 语句产生运行错误。则数据库服务器将 SQLCODE(和 sqlca.sqlcode)
设置为负值。实际数标识特定错误。错误消息文档列出了 GBase 8s 特定的错误代码和它
们的修改操作。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 306 -
从 GBase 8s ESQL/C 程序中,您可以使用 rgetlmsg() 或 rgetmsg() 库函数来检索与
负 SQLCODE(sqlca.sqlcode)值相关联的错误消息文本。
当数据库服务器遇到运行错误时,它还会设置 sqlca 结构中的以下其它字段:
sqlca.sqlerrd[1] 保存附加的 ISAM 错误返回代码。
还可以使用 rgetlmsg() 和 rgetmsg()
库函数获取 ISAM 错误消息文本。
sqlca.sqlerrd[2] 指示在多行 INSERT 、
UPDATE 或 DELETE 语句中发生错误之前处
理的行数。
根据数据库服务器正在使用的类型,sqlca.sqlerrm 的使用方式有所不同。
如果服务器是 GBase 8s 数据库服务器,则此值设置为错误消息参数。该值用于替换
错误消息中的 %s 令牌。
例如,在以下错误消息中,(sam.xyz)表的名称保存在 sqlca.sqlerrm 中:
310: Table (sam.xyz) already exists in database.
如果服务器是 DB2 数据库服务器,则将此字段设置为完整的错误消息。
在执行 PREPARE 、EXECUTE IMMEDIATE 或 DECLARE 语句遇到错误后设置
sqlca.sqlerrd[4]。
提示: 还可以使用 WHENEVER SQLERROR 语句测试错误。
PREPARE 语句执行之后的错误
当数据库服务器返回 PREPARE 语句的错误时,
该错误通常是因为准备的文本中的语
法错误。当发生此错误时,数据库服务器返回以下信息:
SQLCODE 变量指示错误的原因。
sqlca.sqlerrd[4] 字段包含发生错误的准备语句文本中的偏移量。您的程序可以使用
sqlca.sqlerrd[4] 中的值来指示动态准备文本的语法在哪里不正确。
如果使用一个 PREPARE 语句准备多个语句,
则数据库服务器将在文本中的第一个错
误上返回错误状态,即使它遇到多个错误。
重要: 由于 GBase 8s ESQL/C 预处理器将嵌入式 SQL 语句转换为主机语言格式,
所以将错误偏移到 SQL 语句中的 sqlerrd[4] 字段可能并不总是正确的。这样做,预处理
器可能会改变嵌入语句中元素的相对位置。
例如,考虑以下语句,其包含无效的 WHERE 子句:
EXEC SQL INSERT INTO tab VALUES (:x, :y, :z)
WHERE i = 2;
预处理器将此语句转换为类似于以下字符串的字符串:
" insert into tab values ( ? , ? , ? ) where i = 2 "
该字符串不具有 EXEC SQL 关键字。
另外,
字符 ?, ?, ? 已经替换 :x, :y, :z (五
个字符而不是八个字符)。GBase 8s ESQL/C 预处理器也在左括号(")")和 WHERE 关

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 307 -
键字之间删除了一个换行符。因此,数据库服务器看到的 SQL 语句中的错误偏移量与嵌
入式 SQL 语句中错误的偏移量不同。
sqlca.sqlerrd[4] 字段还会报告 EXECUTE IMMEDIATE 和 DECLARE 语句中的
错误的语句偏移量。
执行 EXECUTE 语句后的 SQLCODE
执行 EXECUTE 语句后,数据库服务器设置 SQLCODE 以指示准备语句的成功,
如下所示:
如果数据库服务器不能成功执行准备的语句,则它将 SQLCODE 设置为小于 0 的值。
SQLCODE 变量保存数据库服务器从失败的语句返回的错误。
如果数据库服务器可以成功执行块中准备的语句,则将 SQLCODE 设置为 0;如果
预备的块包括多个语句,则所有的语句成功。
显示错误文本(Windows)
GBase 8s ESQL/C 应用程序使用 GBase 8s ERRMESS.HLP 文件显示描述错误及其修
正确操作的文本。
可以调用具有以下 WinHelp 参数的 Windows™ API WinHelp()。
WinHelp 参数
事件
HELP_CONTEXT
SQLCODE 或 sqlca.sqlcode 的错误号
HELP_CONTEXTPOPUP
SQLCODE 或 sqlca.sqlcode 的错误号
HELP_KEY
指向包含 SQLCODE 或 sqlca.sqlcode 中的错误编号的字符串,
并使用 sprintf()
或 wsprintf() 转换为 ASCII
HELP_PARTIALKEY
指向包含 SQLCODE 或 sqlca.sqlcode 中的错误编号的字符串,
并使用 sprintf()
或 wsprintf() 转换为 ASCII

STATIO_USER_TABLES 视图显示命名空间中所有用户关系表的IO 状态信息。
名称
类型
描述
relid
oid
表OID。
schemaname
name
该表模式名。
relname
name
表名。
heap_blks_read
bigint
从该表中读取的磁盘块数。
heap_blks_hit
bigint
该表缓存命中数。
idx_blks_read
bigint
从表中所有索引读取的磁盘块数。
idx_blks_hit
bigint
表中所有索引命中缓存数。
toast_blks_read
bigint
该表的TOAST 表读取的磁盘块数(如果存在)。
toast_blks_hit
bigint
该表的TOAST 表命中缓冲区数(如果存在)。
tidx_blks_read
bigint
该表的TOAST 表索引读取的磁盘块数(如果存在)。
tidx_blks_hit
bigint
该表的TOAST 表索引命中缓冲区数(如果存在)。


GBase 8s 管理员参考
南大通用数据技术股份有限公司 - 109 -
使用 MULTIPROCESSOR 配置参数来指定数据库服务器是否以一种适合于单处理器计算机或
多处理器计算机的方式执行锁定。
如果 MULTIPROCESSOR 设置为 0,则忽略设置处理器 GBase 8s affinity 的参数。
onconfig.std 值
MULTIPROCESSOR 0

0 = 无多处理器
1 = 多处理器可用
生效
编辑 onconfig 文件并重启数据库服务器之后。