返回首页

gbase数据、南大通用产品文档:GBase8s字符和字符串数据类型

更新日期:2024年09月11日

这些主题介绍了如何在 GBase 8s ESQL/C 程序中使用字符数据类型。

缺省情况下,
GBase 8s ESQL/C 应用程序不会执行任何 SQL 语句的异常处理。
因此,
除非您显式提供这些代码,否则在执行时继续执行。虽然这种行为对于成功执行、警告和
NOT FOUND 条件可能不太严重,但是在运行错误的情况下可能产生严重后果。
运行错误可能会停止程序执行。除非您在应用程序代码中检查并梳理这些错误,否则
这种行为可能会导致用户混淆和困惑。它还使应用程序处于不一致的状态。

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

在 GBase 8s ESQL/C 应用程序中,请为异常处理选择一致的策略。可以选择以下一
种异常处理策略:
可以在每条 SQL 语句执行后检查,这意味着您在每个 SQL 语句之后包含测试
SQLSTATE (或 SQLCODE)值的代码。
可以使用 WHENEVER 语句将响应关联到每次发生特定类型的异常的时候。
重要: 请在开发前考虑如何在应用程序中执行异常处理,以致于可以采取一致和可
维护的方法。
在执行每条 SQL 语句后检查
要检查异常,可以包含代码来显式测试 SQLSTATE(或 SQLCODE)的值。
提示: 请确定使用 SQLSTATE (和诊断区域)或 SQLCODE(和 sqlca 结构)来
确定异常值。选择的异常处理变量需一致。如果混淆这两个变量,则您创建的代码很难维
护。请记住在这两个选项中 SQLSTATE 更灵活更便捷。
例如,如果要使用 SQLSTATE 检查 CREATE DATABASE 语句是否按期望执行,
则可以使用下图显示的代码。
图: 使用 SQLSTATE 测试错误是否是在 SQL 语句执行期间执行statement
EXEC SQL create database personnel with log;
if(strncmp(SQLSTATE, "02", 2) > 0) /* > 02 is an error */
{
EXEC SQL get diagnostics exception 1
:message = MESSAGE_TEXT, :messlen = MESSAGE_LENGTH;
message[messlen] ='\0'; /* terminate the string. */

printf("SQLSTATE: %s, %s\n", SQLSTATE, message);
exit(1);
}
作为备选方案,可以编写处理任何异常的异常处理函数。您的程序然后可以在每个
SQL 语句之后调用一个异常处理函数。
下图显示的 sqlstate_exception() 函数是异常处理函数的示例,它使用 SQLSTATE
变量和诊断区域检查警告、
NOT FOUND 条件和运行错误。
它在每条 SQL 语句之后调用。
图: 使用 SQLSTATE 的异常处理函数的示例
EXEC SQL select * from customer where fname not like "%y";
sqlstate_exception("select");


int4 sqlstate_exception(s)
char *s;
{
int err = 0;

if(!strncmp(SQLSTATE, "00", 2) ||

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

!strncmp(SQLSTATE,"02",2))
return(SQLSTATE[1]);

if(!strncmp(SQLSTATE, "01", 2))
printf("\n********Warning encountered in %s********\n",
statement);
else /* SQLSTATE class > "02" */
{
printf("\n********Error encountered in %s********\n",
statement);
err = 1;
}

disp_sqlstate_err(); /* See the getdiag sample program */
if(err)
{
printf("********Program terminated*******\n\n");
exit(1);
}

/*
* Return the SQLCODE
*/
return(SQLCODE);
}
图 2中显示的 sqlstate_exception() 函数处理下列异常:
如果语句成功,则 sqlstate_exception() 返回零。
如果在 SELECT 或 FETCH 语句发生 NOT FOUND 条件,则 sqlstate_exception()
返回值 2。
如果发生警告或运行错误—即,如果 SQLSTATE 的前两个字节是 "01"(警告)
或大于 "02" (错误)— sqlstate_exception() 函数调用 disp_sqlstate_err() 函数显示异常信
息。0
如果 SQLSTATE 指示错误,
则 sqlstate_exception() 函数使用 exit() 系统调用退出
程序。如果不调用 exit(),则会在发生错误的一个语句后的下一个 SQL 语句继续执行。
要处理错误,sqlstate_exception() 函数可以省略 exit() 调用,并允许执行继续执行。
在此情况中,函数必须返回 SQLSTATE 或 SQLCODE(特定于 GBase 8s 的错误)
值,而此调用的程序可以确定对此运行错误采取哪种操作。
WHENEVER 语句
可以使用 WHENEVER 语句追踪 SQL 语句执行期间的发生异常。
WHENEVER 语句提供下列信息:
检查哪些条件:

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

SQLERROR 检查 SQL 语句是否失败。当数据库服务器将 SQLCODE
(sqlca.sqlcode)设置为负值,并将 SQLSTATE 的类代码设置为大于 "02" 的值时,应
用程序执行特定的操作。
NOT FOUND 检查是否找到特定的数据。当数据库服务器将 SQLCODE
(sqlca.sqlcode)
设置为 SQLNOTFOUND ,
并将 SQLSTATE 的类代码设置为 "02" 时,
应用程序执行特定的操作。
SQLWARNING 检查 SQL 语句是否生成警告。当数据库服务器将
sqlca.sqlwarn.sqlwarn0
(某些 sqlca.sqlwarn 的其它字段)
设置为 W ,
并将 SQLSTATE
的类代码设置为 "01" 时,应用程序执行特定的操作。
在 Windows™ 环境中,不能在要编译为 DLL 的 GBase 8s ESQL/C 程序中使用
WHENEVER ERROR STOP 约束。.
当特定条件发生时,采用什么操作:
CONTINUE 忽略此异常并在 SQL 语句之后的下一个语句中继续执行。
GO TO label 键异常传输到指定 label 介绍的代码节。
STOP 立即停止程序执行。
CALL 函数名称将执行传输到指定的函数名称。
如果不存在 WHENEVER 语句符合给出的条件,则 GBase 8s ESQL/C 预处理器使用
CONTINUE 作为缺省的操作。
要在每次错误发生时执行 sqlstate_exception() 函数
(如图 2
所示示),可以使用 WHENEVER SQLERROR 语句的 GOTO 操作,如果指定了
WHENEVER 的 SQLERROR 条件,则可以获得与每个 SQL 语句之后检查 SQLCODE
或 SQLSTATE 变量的错误相同的行为。
GOTO 操作的 WHENEVER 语句可以采取以下两种形式:
ANSI 标准形式使用关键字 GOTO (一个词),并使用冒号(:)引入标签名称:
EXEC SQL whenever goto :error_label;
GBase 8s 扩展使用关键字 GO TO(两个词)并仅指定 label 名称:
EXEC SQL whenever go to error_label;
使用 GOTO 操作,当 SQL 语句生成异常时,程序会自动将控件传输到 error_label
标签。
当使用 WHENEVER 语句的 GOTO label 操作时,
您的代码必须包含标签和适当逻
辑来处理错误条件。在以下示例中, label 中的逻辑只是调用 sqlstate_exception() 函数:
error_label:
sqlstate_exception (msg);
您必须在包含 SQL 语句的每个程序块中定义此 error_label 标签。
如果您的程序包
含多个函数,则可能需要在每个函数中包含 error_label 标签和代码。否则,预处理器到
达不包含 error_label 的函数时会产生错误。
它尝试插入 WHENEVER...GOTO 语句请求
的代码,但该函数尚未定义 error_label 标签。

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

要删除预处理器错误,您可以在每个函数中放置带有相同标签名称的带标签的语句,
您可以为 WHENEVER 语句发出另一个操作来重置错误条件,也可以使用 CALL 操作替
换 GOTO 操作,以调用分离函数。
当错误发生时,还可以在 WHENEVER 语句中使用 CALL 关键字调用
sqlstate_exception() 函数。(CALL 选项是 ANSI 标准的 GBase 8s 扩展名。)
如果您要在程序中每次发生 SQL 错误时调用 sqlstate_exception() 函数,请执行以下
步骤:
修改 sqlstate_exception() 函数,使其不需要任何参数。 CALL 操作指定的函数不能
接受参数。要传递信息,请改用全局变量。
在任何 SQL 语句之前,将以下 WHENEVER 语句放置程序的前面部分:
EXEC SQL whenever sqlerror call sqlstate_exception;
提示: 在之前的代码段中,不能在 sqlstate_exception() 函数之后包含括号。
但是,请确保,WHENEVER...CALL 影响的所有函数都可以找到 sqlstate_exception()
函数的声明。


GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1101
语法格式
SET [GLOBAL | SESSION] =
表5- 112 参数说明
参数名称


SESSION
省略掉SESSION 关键字,也就是默认情况下,是会话
(SESSION)级别的,即只在集群中执行该命令的节点机器
上的当前连接设定成功,其他节点不变。
GLOBAL
设置为此关键字时,新的变量值将被用于新的连接当中。
variable_name
变量名。
value
变量值。
示例
示例1:默认为会话级别,只在当前节点机器上的当前连接有效。
gbase> SET AUTOCOMMIT = 1;
Query OK, 0 rows affected
示例2:使用GLOBAL 关键字,设置“gbase_sql_trace”的值为“on”。
gbase> SHOW VARIABLES LIKE '%trace%';
+----------------------------+-------+
| Variable_name
| Value |
+----------------------------+-------+
| _gbase_sql_trace_file_mode | OFF
|
| auto_trace
| OFF
|
| gbase_sql_trace
| OFF
|
| gbase_sql_trace_level
| 0
|
+----------------------------+-------+
4 rows in set
gbase> SET GLOBAL gbase_sql_trace =on;
Query OK, 0 rows affected
gbase> SHOW VARIABLES LIKE '%gbase_sql_trace%';
+----------------------------+-------+
| Variable_name
| Value |
+----------------------------+-------+
| _gbase_sql_trace_file_mode | OFF
|
| gbase_sql_trace
| OFF
|
| gbase_sql_trace_level
| 0
|
+----------------------------+-------+

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1102
3 rows in set
gbase> QUIT
Bye
# gccli -uroot -p
Enter password:
GBase client 9.5.3.17.117651. Copyright (c) 2004-2019, GBase.
All Rights
Reserved.
gbase> SHOW VARIABLES LIKE '%trace%';
+----------------------------+-------+
| Variable_name
| Value |
+----------------------------+-------+
| _gbase_sql_trace_file_mode | OFF
|
| auto_trace
| OFF
|
| gbase_sql_trace
| ON
|
| gbase_sql_trace_level
| 0
|
+----------------------------+-------+
4 rows in set