返回首页

gbase数据、南大通用产品文档:GBase8s数据库服务器运行方式

更新日期:2024年09月11日

可以通过从命令行运行 onstat 实用程序来确定当前的数据库服务器方式。
onstat 头将显
示该方式。
下表显示了数据库服务器的主要运行方式。
表 1. 运行方式
运行方式
描述
允许访问的用户
脱机方式
数据库服务器未在运行。
共享内
存未被分配。
只有管理员(用户 gbasedbt)可以
从此方式更改为其他方式。
静默方式
数据库服务器进程正在运行并
且共享内存资源已被分配。
管理员使用此方式执行不需要
执行 SQL 和 DDL 语句的维护
功能。
只有管理员(用户 gbasedbt)可以
访问数据库服务器。
其他用户可查看数据库服务器状态
信息,但他们不能访问数据库服务
器。
管理方式
此方式是一种介于静默方式和
联机方式之间的中间方式。
管理员使用此方式执行所有维
护任务,
其中包括需要执行 SQL
和 DDL 语句的任务。管理员还
可以执行在联机方式中可用的
所有其他功能。
以下用户可在管理方式下连接到数
据库服务器:

gbasedbt 用户

具有 DBSA 角色的用户
如果您想要属于 DBSA 组成员的
用户(除用户 gbasedbt 外)以
管理方式连接到数据库服务器,
请将
ADMIN_USER_MODE_WITH_DBSA 配
置参数设置为 1。

具有管理方式访问权限的一

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 76 -
运行方式
描述
允许访问的用户
个或多个用户
用户 gbasedbt 或 DBSA 可通过
onmode -j 命令、oninit -U 命
令或 ADMIN_MODE_USERS 配置参
数动态地授予一个或多个特定用
户以管理方式连接到数据库服务
器的能力。
其他用户可查看数据库服务器状态
信息,但他们不能访问数据库服务
器。
联机方式
这是数据库服务器的普通运行
方式。
任何授权用户都可以与数据库服务
器连接并执行所有数据库活动。
用户gbasedbt 或用户 root 可使用
命令行实用程序更改许多服务器
ONCONFIG 参数值。
此外,数据库服务器也可以处于下列方式中的一种:

只读方式由数据复制环境中的辅助数据库服务器使用。应用程序可以查询处于只读
方式下的辅助数据库服务器,但该应用程序不能写入只读数据库。

恢复方式是过渡的。它将在数据库服务器从系统归档或系统复原中执行一个或多个
快速恢复时发生。恢复将在从脱机方式更改到静默方式时发生。

关闭方式是过渡的。它将在数据库服务器从联机方式转到静默方式或从联机(或静
默)方式转到脱机方式时发生。当前用户可以访问系统,但不允许任何新用户访问。
当关闭方式启动后,无法将其取消。

timeout 程序演示如何设置超时间隔。

此程序使用 sqlbreakcallback() 函数执行以下操作:
指定执行 SQL 请求的超时间隔为 200 毫秒 。
要注册在 SQL 请求开始和结束时以及当超时间隔过去时要调用的 on_timeout() 回
调函数。

如果 SQL 请求的执行超出了超时间隔,则回调函数使用 sqldone() 函数确保数据库

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

服务器仍然在忙,提示用户确认中断,然后使用 sqlbreak() 函数发送中断请求到数据库服
务器。
编译程序
使用以下命令编译 timeout 程序:
esql -o timeout timeout.ec

-o timeout 选项将可执行程序命名为 timeout。
不用 -o 选项,
可执行程序的名称缺省
为 a.out。
timeout.ec 文件指南
=================================================================
======
1. /*
2. * timeout.ec *
3. */
4. #include
5. #include
6. #include
7. #include
8. #include
9. EXEC SQL include sqltypes;
10. #define LCASE(c) (isupper(c) ? tolower(c) : (c))
11. /* Defines for callback mechanism */
12. #define DB_TIMEOUT 200 /* number of milliseconds in timeout */
13. #define SQL_INTERRUPT -213 /* SQLCODE value for interrupted stmt
*/
14. /* These constants are used for the canceltst table, created by
15. * this program.
16. */
17. #define MAX_ROWS 10000 /* number of rows added to table */
18. EXEC SQL define CHARFLDSIZE 20; /* size of character columns in
* table */
19. /* Define for sqldone() return values */
20. #define SERVER_BUSY -439

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

21. /* These constants used by the exp_chk2() function to determine
22. * whether to display warnings.
23. */
24. #define WARNNOTIFY 1
25. #define NOWARNNOTIFY 0
26. int4 dspquery();
27. extern int4 exp_chk2();
28. void on_timeout();
29. main()
30. {
31. char ques[80], prompt_ans();
32. int4 ret;
33. mint create_tbl(), drop_tbl();
34. printf("TIMEOUT Sample ESQL Program running.\n\n");
35. /*
36. * Establish an explicit connection to the stores7 database
37. * on the default database server.
38. */
39. EXEC SQL connect to 'stores7';
=================================================================
======

第 4 - 9 行

行 4 - 8 包括来自 /usr/include 目录的 UNIX(TM) 头文件。GBase 8s ESQL/Csqltypes.h
头文件(第 9 行)定义标识 SQL 和 C 的数据类型的整数值。


第 10 - 20 行

第 10 行定义 LCASE,是一个将大写字符转换为小写字符的宏。DB_TIMEOUT(第
12 行)常量定义超时间隔中的毫秒数。 SQL_INTERRUPT 常量(第 13 行)定义数据库
服务器中断 SQL 语句时返回的 SQLCODE 值。

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


第 17 和 18 行定义 create_tbl() 函数用于创建 canceltst 表的常量。
此表保存大查询
所需测试数据
(第 125 - 132)

MAX_ROWS 时 create_tbl() 插入到 canceltst 中的行数。
如果发现查询运行时间不足以阻止该查询,您可以更改此数。CHARFLDSIZE 是 canceltst
的字符字段(char_fld1 和 char_fld2)中的字符数。

第 20 行定义 SERVER_BUSY 常量保存 sqldone() 返回值,来指示数据库服务器是
否正在忙于处理 SQL 请求。使用此常量使代码更可读,并且移除代码显式返回值。


第 24 和 25 行

exp_chk2() 异常处理函数使用 WARNNOTIFY 和 NOWARNNOTIFY 常量(第 24 和
25 行)。调用 exp_chk2() 指定其中的一个作为第二个参数,以指示该函数是
否显示警告信(WARNNOTIFY)的 SQLSTATE 和 SQLCODE 信息,或者不显示警告
信息(NOWARNNOTIFY)。

第 29 - 33 行

main() 程序从第 29 行开始。第 31 - 33 行声明 main() 程序块的本地变量。


=================================================================
======
40. if (exp_chk2("CONNECT to stores7", NOWARNNOTIFY) < 0)
41. exit(1);
42. printf("Connected to 'stores7' on default server\n");
43. /*
44. * Create the canceltst table to hold MAX_ROWS (10,000) rows.
45. */
46. if (!create_tbl())
47. {
48. printf("\nTIMEOUT Sample Program over.\n\n");
49. exit(1);
50. }

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

51. while(1)
52. {
53. /*
54. * Establish on_timeout() as callback function. The callback
55. * function is called with an argument value of 2 when the
56. * database server has executed a single SQL request for number
57. * of milliseconds specified by the DB_TIMEOUT constant
58. * (0.00333333 minutes by default). Call to sqlbreakcallback()
59. * must come after server connection is established and before
60. * the first SQL statement that can be interrupted.
61. */
62. if (sqlbreakcallback(DB_TIMEOUT, on_timeout))
63. {
64. printf("\nUnable to establish callback function.\n");
65. printf("TIMEOUT Sample Program over.\n\n");
66. exit(1);
67. }
68. /*
69. * Notify end user of timeout interval.
70. */
71. printf("Timeout interval for SQL requests is: ");
72. printf("%0.8f minutes\n", DB_TIMEOUT/60000.00);
73. stcopy("Are you ready to begin execution of the query?",
74. ques);
75. if (prompt_ans(ques) == 'n')
76. {
77. /*
78. * Unregister callback function so table cleanup will not
79. * be interrupted.
80. */
81. sqlbreakcallback(-1L, (void *)NULL);
82. break;
83. }

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

=================================================================
======

第 43 - 50 行

create_tbl() 函数在数据库 stores7 中创建 canceltst 表。它插入 MAX_ROWS 数行。
如果 create_tbl() 在创建 canceltst 时遇到错误,
则 timeout 程序不能继续执行。
该程序具
有状态值 1(第49 行)。


第 51 行

while 循环(在第 97 行结束),控制 canceltst 表上的查询。它允许用户多次运行
此查询以测试多种中断场景。


第 53 - 67 行

while 循环的第一要务是使用 sqlbreakcallback() 指定DB_TIMEOUT (200) 的超时间
隔毫秒,并将 on_timeout() 注册为回调函数。如果 sqlbreakcallback() 调用失败,则程序具
有状态值 1。
要测试不同的超时间隔,
可以更改 DB_TIMEOUT 处理并重新编译 timeout.ec
源文件。


第 68 - 72 行

这些 printf() 函数通知用户超时间隔。
请注意,
消息以分钟显示此间隔,
而不是毫秒。
它将 DB_TIMEOUT 值除以 60,000 (一分钟的毫秒数)。


第 73 - 83 行

prompt_ans() 函数要求用户指示何时开始执行 canceltst 查询执行。如果用
户输入 n (否),则程序调用 sqlbreakcallback() 函数取消注册回调函数。

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

此调用阻止 drop_tbl() 函数
(第 322-329 行)
中的 SQL 语句启动调用函数。
有关 prompt_ans() 函数的描述,请参阅第 337 - 347 行。


=================================================================
======
84. /*
85. * Start display of query output
86. */
87. printf("\nBeginning execution of query...\n\n");
88. if ((ret = dspquery()) == 0)
89. {
90. if (prompt_ans("Try another run?") == 'y')
91. continue;
92. else
93. break;
94. }
95. else /* dspquery() encountered an error */
96. exit(1);
97. } /* end while */
98. /*
99. * Drop the table created for this program
100. */
101. drop_tbl();
102. EXEC SQL disconnect current;
103. if (exp_chk2("DISCONNECT for stores7", WARNNOTIFY) != 0)
104. exit(1);
105. printf("\nDisconnected stores7 connection\n");
106. printf("\nTIMEOUT Sample Program over.\n\n");
107. }
108. /* This function performs the query on the canceltst table. */
109. int4 dspquery()
110. {
111. mint cnt = 0;

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

112. int4 ret = 0;
113. int4 sqlcode = 0;
114. int4 sqlerr_code, sqlstate_err();
115. void disp_exception(), disp_error(), disp_warning();
116. EXEC SQL BEGIN DECLARE SECTION;
117. char fld1_val[ CHARFLDSIZE + 1 ];
118. char fld2_val[ CHARFLDSIZE + 1 ];
119. int4 int_val;
120. EXEC SQL END DECLARE SECTION;
121. /* This query contains an artificially complex WHERE clause to
122. * keep the database server busy long enough for an interrupt
123. * to occur.
124. */
125. EXEC SQL declare cancel_curs cursor for
126. select sum(int_fld), char_fld1, char_fld2
127. from canceltst
128. where char_fld1 matches "*f*"
129. or char_fld1 matches "*h*"
130. or char_fld2 matches "*w*"
131. or char_fld2 matches "*l*"
132. group by char_fld1, char_fld2;
=================================================================
======

第 84 - 97 行

如果用户选择继续查询,
则此程序调用 dspquery() 函数
(第 88 行)
运行 canceltst 查
询,prompt_ans() 函数显示提示,以便用户可以决定是否再次运行该程序。


第 98 - 101 行

drop_tbl() 函数从 stores7 数据库删除 canceltst 表,以便程序清理。

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



第 108 - 120 行

dspquery() 函数返回 canceltst 表的查询并显示结果。它返回零(成功)或者
SQLCODE 负值(失败)来指示 canceltst 查询的结果。


第 121 - 132 行

第 125 行为此游标声明 cancel_curs 游标。实际 SELECT (第 126 - 132 行)包含
int_fld 列和两个字符列(char_fld1 和 char_fld2)的值的总和。WHERE 子句使用
MATCHES 运算符来指定匹配的行,如下所示: follows:
包含 f 或 h 的所有的 char_fld1 列都包含以下条件:
char_fld1 matches "*f*"
or char_fld1 matches "*h*"
这些条件与 Gbasedbt 或"4100 Bohannon Dr." 的 char_fld1 值匹配。

包含 w 或 l 的所有的 char_fld2 列都包含以下条件:
char_fl2 matches "*w*"
or char_fld2 matches "*l*"
这些条件与 Software 或 "Menlo Park, CA" 的 char_fld2 值相匹配。

此 SELECT 是人为复制的,以确保查询需要很长时间才能执行。没有相当复杂的查
询,数据库服务器在用户有机会中断之前完成执行。在生产应用程序中,只能使用
sqlbreakcallback() 功能与需要很长时间执行的查询。


=================================================================
======
EXEC SQL open cancel_curs;
sqlcode = SQLCODE;
sqlerr_code = sqlstate_err(); /* check SQLSTATE for exception */

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

if (sqlerr_code != 0) /* if exception found */
{
if (sqlerr_code == -1) /* runtime error encountered */
{
if (sqlcode == SQL_INTERRUPT) /* user interrupt */
{
/* This is where you would clean up resources */
printf("\n TIMEOUT INTERRUPT PROCESSED\n\n");
sqlcode = 0;
}
else /* serious runtime error */
disp_error("OPEN cancel_curs");
EXEC SQL close cancel_curs;
EXEC SQL free cancel_curs;
return(sqlcode);
}
else if (sqlerr_code == 1) /* warning encountered */
disp_warning("OPEN cancel_curs");
}
=================================================================
======

第 133 行

OPEN 函数使数据库服务器执行与 cancel_curs 游标关联的 SELECT 。因为数据库
服务器执行 canceltst 查询,此 OPEN 是用户最优可能中断的语句。当 FETCH 执行时,
数据库服务器仅发送匹配的行到应用程序,这种操作通常并不耗时。


第 134 - 154 行

此代码检查 OPEN 的成功。因为 OPEN 可以被中断,所以此异常检查必须包含中断
值为 -213 的显式检查。
数据库服务器在中断一个 SQL 请求时将 SQLCODE 设置为 -213。
在第 140 行,
程序为 SQLCODE 值使用 SQL_INTERRUPT 定义常量
(第 13 行定义)


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


sqlstate_err() 函数(第 135 行)使用 GET DIAGNOSTICS 语句分析 SQLSTATE 变
量的值。
如果此函数返回非零值,
则 SQLSTATE 指示警告,
运行错误或 NOT FOUND 条
件。
在调用 sqlstate_err() 之前,
第 134 行保存 SQLCODE 值,
以便任何其它执行的 SQL
语句(如 sqlstate_err() 中的 GET DIAGNOSTICS)不会重写它。如果 OPEN 语句遇到运
行错误该函数返回 SQLCODE 的值(第 150 行)

如果 OPEN 遇到任何种类的异常
(sqlstate_err() 返回非零值)

则第一个 if 语句
(136
行)检查。如果 OPEN 已经生成了运行错误(返回值为 -1),则第二个 if(138 行)检
查。
但是,
如果数据库服务器打断了 OPEN,
则 sqlstate_err() 也会返回 -1。
因为 GBase 8s
ESQL/C 不会将打断的 SQL 语句作为运行错误处理。所以第三个 if 显式检查
SQL_INTERRUPT 值(140 行)。如果 OPEN 被打断,则 143 行通知用户打断的请求成
功然后还是重新将保存的 SQLCODE 值(sqlcode 中)设置为零,以指示 OPEN 没有生
成运行错误。

第 146 和 147 行只在 OPEN 生成运行错误时执行,而不是在 SQL_INTERRUPT
(-213)
时。
disp_error() 函数显式诊断区域中的异常信息和 SQLCODE 值。
第 148 - 150 行
在 OPEN 后清除。它们关闭并释放 cancel_curs 游标,然后返回 SQLCODE 值。如果
OPEN 被中断,则 dspquery() 函数不会使用 FETCH (158 行)继续。

如果 sqlstate_err() 返回一(1),则 OPEN 生成警告。第 152 和 153 行调
用 disp_warning() 函数显示来自诊断区域的警告信息。有关 disp_error()
和 disp_warning() 函数的更多信息,请参阅 第 348 - 355 行。


=================================================================
======
155. printf("Displaying data...\n");
156. while(1)
157. {
158. EXEC SQL fetch cancel_curs into :int_val, :fld1_val,
:fld2_val;
159. if ((ret = exp_chk2("FETCH from cancel_curs", NOWARNNOTIFY))
== 0)
160. {
161. printf(" sum(int_fld) = %d\n", int_val);

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

162. printf(" char_fld1 = %s\n", fld1_val);
163. printf(" char_fld2 = %s\n\n", fld2_val);
164. }
165. /*
166. * Will display warning messages (WARNNOTIFY) but continue
167. * execution when they occur (exp_chk2() == 1)
168. */
169. else
170. {
171. if (ret==100) /* NOT FOUND condition */
172. {
173. printf("\nNumber of rows found: %d\n\n", cnt);
174. break;
175. }
176. if (ret < 0) /* Runtime error */
177. {
178. EXEC SQL close cancel_curs;
179. EXEC SQL free cancel_curs;
180. return(ret);
181 . }
182. }
183. cnt++;
184. } /* end while */
185. EXEC SQL close cancel_curs;
186. EXEC SQL free cancel_curs;
187. return(0);
188. }
189. /*
190. * The on_timeout() function is the callback function. If the user
191. * confirms the cancellation, this function uses sqlbreak() to
192. * send an interrupt request to the database server.
193. */
194. void on_timeout(when_called)

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

195. mint when_called;
196. {
197. mint ret;
198. static intr_sent;
=================================================================
======

第 155 - 182 行

while 循环对 cancel_curs 游标包含的每一行执行。 FETCH 语句(第 158 行) 从
cancel_curs 游标检索一行。如果 FETCH 生成错误,则函数释放游标资源并返回
SQLCODE 错误值(第 176 - 181 行)。否则,此函数向用户显示检索到的数据。在最后
一行(ret = 100),该函数显示它检索到的行数(173 行)。


第 185 - 187 行

在 FETCH 从游标检索到最后一行后,
该函数将释放分配给 cancel_curs 游标的资源,
并返回成功值为零。


第 190 - 198 行

on_timeout() 函数是 timeout 程序的回调函数。62 行调用 sqlbreakcallback() 注册此
函数并建立一个 200 毫秒的超时间隔。每次在数据库服务器开始或结束 SQL 请求时调用
此函数。对于长时间运行请求,应用程序在每次超时时间间隔调用调用 on_timeout()。


=================================================================
======
199. /* Determine when callback function has been called. */
200. switch(when_called)
201. {
202. case 0: /* Request to server completed */

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

203. printf("+------SQL Request ends");
204. printf("-------------------------------+\n\n");
205. /*
206. * Unregister callback function so no further SQL statements
207. * can be interrupted.
208. */
209. if (intr_sent)
210. sqlbreakcallback(-1L, (void *)NULL);
211. break;
212. case 1: /* Request to server begins */
213. printf("+------SQL Request begins");
214. printf("-----------------------------+\n");
215. printf("| ");
216. printf(" |\n");
217. intr_sent = 0;
218. break;
219. case 2: /* Timeout interval has expired */
220. /*
221. * Is the database server still processing the request?
222. */
223. if (sqldone() == SERVER_BUSY)
224. if (!intr_sent) /* has interrupt already been sent? */
225. {
226. printf("| An interrupt has been received ");
227. printf("by the application.|\n");
228. printf("| ");
229. printf(" |\n");
230. /*
231. * Ask user to confirm interrupt
232. */
233. if (cancel_request())
234. {
235. printf("| TIMEOUT INTERRUPT ");

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

236. printf("REQUESTED |\n");
237. /*
238. * Call sqlbreak() to issue an interrupt request for
239. * current SQL request to be cancelled.
240. */
241. sqlbreak();
242. }
243. intr_sent = 1;
244. }
245. break;
=================================================================
======

第 199 - 249 行

switch 语句使用回调函数参数 when_called 确定回调函数的操作,如下所示:
第 202 - 211 行:如果 when_called 是 0,则在数据库服务器服务器结束 SQL 请求
后调用回调函数。消息请求框底部显示此消息,显示 SQL 语句的结束,如下所示:
+------SQL Request ends-------------------------------+
第 212 - 218 行:如果 when_called 是 1,则在数据库服务器开始 SQL 请求时调用
此回调函数。消息请求框顶部的显示指示此条件:
+------SQL Request begins-----------------------------+
| |
有关这些消息请求框的更多信息,请参阅 第 21 - 30 行。此函数还指示
intr_sent 标记为 0,因为用户尚未发送此 SQL 请求的中断。

第 219 - 245 行:如果 when_called 是 2,则调用此回调函数,因为超时间隔已过。

为了处理已过的超时间隔,回调函数首先调用 GBase 8s ESQL/Csqldone() 函数(第
223 行)来确定数据库服务器是否仍在处理 SQL 请求。如果数据库服务器空闲,则应用
程序不需要发送中断。如果 sqldone() 返回 SERVER_BUSY (-439),则数据库服务器仍在
忙。

224 行检查用户是否已尝试中断正在执行的 SQL 请求。如果发送了中断,

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

则 intr_sent 是 1,程序不需要发送另一个请求。如果中断请求还尚未发送,
则回调函数通知用户超时间隔已过(第 226 - 229 行)。它然后使用
cancel_request() 函数(第 233 行)允许用户确认此中断。有关
cancel_request() 的更多信息, 请参阅第 251 - 261 行。


=================================================================
======
246. default:
247. printf("Invalid status value in callback: %d\n", when_called);
248. break;
249. }
250. }
251. /* This function prompts the user to confirm the sending of an
252. * interrupt request for the current SQL request.
253. */254. mint cancel_request()
255. {
256. char prompt_ans();
257. if (prompt_ans("Do you want to confirm this interrupt?") == 'n')
258. return(0); /* don't interrupt SQL request */
259. else
260. return(1); /* interrupt SQL request */
261. }
262. /* This function creates a new table in the current database. It
263. * populates this table with MAX_ROWS rows of data. */
264. mint create_tbl()
265. {
266. char st_msg[15];
267. int ret = 1;
268. EXEC SQL BEGIN DECLARE SECTION;
269. mint cnt;
270. mint pa;
271. mint i;
272. char fld1[ CHARFLDSIZE + 1 ], fld2[ CHARFLDSIZE + 1 ];

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

273. EXEC SQL END DECLARE SECTION;
274. /*
275. * Create canceltst table in current database
276. */
277. EXEC SQL create table canceltst (char_fld1 char(20),
278. char_fld2 char(20), int_fld integer);
279. if (exp_chk2("CREATE TABLE", WARNNOTIFY) < 0)
280. return(0);
281. printf("Created table 'canceltst'\n");
282. /*
283. * Insert MAX_ROWS of data into canceltst
284. */
285. printf("Inserting rows into 'canceltst'...\n");
286. for (i = 0; i < MAX_ROWS; i++)
187. {
=================================================================
======

第 199 - 249 行(接上行)

如果用户确认中断,则回调函数调用 sqlbreak() 函数发送中断请求到数据库服务器。
回调函数不等待数据库服务器响应中断请求。执行继续到行 243,并将 intr_sent 标志设
置为 1,来显示中断请求已发送。如果使用无效参数的值(0 、1 或 2 以外的值)调用回
调函数,该函数将显示错误消息(第 247 行)。


第 251 - 261 行

cancel_request() 函数询问用户确认中断请求。它显示以下提示:
Do you want to confirm this interrupt?

如果用户回应 y (是)则 cancel_request() 返回 0。如果用户回应 n(否),则
cancel_request() 返回 1。

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



第 262 - 281 行

create_tbl() 函数创建 canceltst 表,
并将测试数据插入到此表中。
CREATE TABLE 语
句(第 277 和 278 行)创建具有三列 int_fld 、char_fld1 和 char_fld2 的 canceltst表。
如果 CREATE TABLE 遇到错误,则 exp_chk2() 函数(第 279 行)显示诊断区域信息,
create_tbl() 返回 0 来显示错误语句发生。


第 282 - 287 行

此 for 循环控制 canceltst 行的插入。MAX_ROWS 处理为此循环确定迭代次数,因
此确定函数插入到表中的行数。
如果由于执行速度太快而无法中断 canceltst 查询
(第 126
- 132 行),请增加 MAX_ROWS 的值并重新编译 timeout.ec 文件。


=================================================================
======
288. if (i%2 == 1) /* odd-numbered rows */
289. {
290. stcopy("4100 Bohannan Dr", fld1);
291 stcopy("Menlo Park, CA", fld2);
292. }
293. else /* even-numbered rows */
294. {
295. stcopy("Gbasedbt", fld1);
296. stcopy("Software", fld2);
297. }
298. EXEC SQL insert into canceltst
299. values (:fld1, :fld2, :i);
300. if ( (i+1)%1000 == 0 ) /* every 1000 rows */
301. printf(" Inserted %d rows\n", i+1);
302. sprintf(st_msg, "INSERT #%d", i);

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

303. if (exp_chk2(st_msg, WARNNOTIFY) < 0)
304. {
305. ret = 0;
306. break;
307. }
308. }
309. printf("Inserted %d rows into 'canceltst'.\n", MAX_ROWS);
310. /*
311. * Verify that MAX_ROWS rows have added to canceltst
312. */
313. printf("Counting number of rows in 'canceltst' table...\n");
314. EXEC SQL select count(*) into :cnt from canceltst;
315. if (exp_chk2("SELECT count(*)", WARNNOTIFY) < 0)
316. return(0);
317. printf("Number of rows = %d\n\n", cnt);
318. return (ret);
319. }
320. /* This function drops the 'canceltst' table */
321. mint drop_tbl()
322. {
323. printf("\nCleaning up...\n");
324. EXEC SQL drop table canceltst;
325. if (exp_chk2("DROP TABLE", WARNNOTIFY) < 0)
326. return(0);
327. printf("Dropped table 'canceltst'\n");
328. return(1);
329. }
=================================================================
======

第 288 - 292 行

此 if 语句生成 canceltst 表的 char_fld1 和 char_fld2 列的值。第 290 行和 291

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

行执行奇数行。它们将字符串 "4100 Bohannon Dr" 和 "Menlo Park, CA" 存储在 fld1 和
fld2 变量中。


第 293 - 297 行

第 295 和 296 行对偶数行执行。它们将字符 Gbasedbt 和 Software 存储在 fld1 和
fld2 变量中。


第 298 - 307 行

INSERT 语句将行插入到 canceltst 表中。它从 :i 主机变量(行号)采用 int_fld 列
的值,采用 :fld1 主变量 char_fld1 和 char_fld2 列的值。该函数在每插入 1000 行后,
通知用户
(第 300 和 301 行)

如果 INSERT 遇到错误,
则 exp_chk2() 函数
(第 303 行)
显示诊断区域信息,create_tbl() 返回零来指示发生错误。


第 300 - 317 行

这些行验证程序已将行添加到 canceltst 表中,并且可以访问它们,程序在新创建的
canceltst 表上执行 SELECT ,并返回找到的行数。该程序检查该号码是否与函数添加的
号码相匹配,该行显示的是哪一行。如果遇到错误,则 exp_chk2() 函数(第 315 行)显
示诊断区域信息,并且 create_tbl() 返回 0 以指示发生错误。


第 320 - 329 行

drop_tbl() 函数从当前数据库删除 canceltst 表。
如果 DROP TABLE 语句
(第 324 行)
遇到错误,则 exp_chk2() 函数显示诊断区域信息,drop_tbl() 返回 0 以指示发生错误。


=================================================================
======

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

330. /*
331. * The inpfuncs.c file contains the following functions used in
this
332. * program:
333. * getans(ans, len) - accepts user input, up to 'len' number of
334. * characters and puts it in 'ans'
335. */
336. #include "inpfuncs.c"
337. char prompt_ans(question)
338. char * question;
339. {
340. char ans = ' ';
341. while(ans != 'y' && ans != 'n')
342. {
343. printf("\n*** %s (y/n): ", question);
344. getans(&ans,1);
345. }
346. return ans;
347. }
348. /*
349. * The exp_chk() file contains the exception handling functions to
350. * check the SQLSTATE status variable to see if an error has
* occurred
351. * following an SQL statement. If a warning or an error has
352. * occurred, exp_chk2() executes the GET DIAGNOSTICS statement and
353. * displays the detail for each exception that is returned.
354. */
355. EXEC SQL include exp_chk.ec;
=================================================================
======

第 330 - 336 行


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

某些 GBase 8s ESQL/C 演示程序还会调用 getans() 函数。因此,该函数被分解为一
个独立的 C 源文件并在适当的演示程序中包含。
因为此函数不包含 GBase 8s ESQL/C,

以查询可以使用 C #include 预处理器语句包含此文件。

第 337 - 347 行

prompt_ans() 函数显示 question 参数中的字符串并等待用户输入 y
(是)
或 n
(否)
作为回应。它返回单个字符响应。


第 348 - 355 行

timeout 程序使用 exp_chk2() 、sqlstate_err() 、disp_error() 和
disp_warning() 函数执行它的异常处理。因为几个演示程序使用这些函数,所
以 exp_chk2() 函数及其支持的函数放在单独的 exp_chk.ec 源文件中。
timeout 程序必须包含具有 GBase 8s ESQL/Cinclude 伪指令的程序,因为异
常处理函数使用GBase 8s ESQL/C 语句。

提示: 在生产环境中,将 getans() 、exp_chk2() 、sqlstate_err() 、disp_error() 和
disp_warning() 函数放到库中并在 GBase 8s ESQL/C 编译程序的命令行包含此库。
示例输出
本节包含 timeout 演示程序的示例输出。

该程序执行两次 canceltst 查询,如下所示:
第 20 - 43 行:一旦出现确认提示,第一次运行就会确认中断请求。(用户输入 y)
第 44 - 75 行:第二次运行不会确认中断请求(用户输入 n)

以下输出中出现的数字仅供参考,它们不会出现在实际的程序输出中。

=================================================================
======
1. TIMEOUT Sample ESQL Program running.
2. Connected to 'stores7' on default server
3. Created table 'canceltst'

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

4. Inserting rows into 'canceltst'...
5. Inserted 1000 rows
6. Inserted 2000 rows
7. Inserted 3000 rows
8. Inserted 4000 rows
9. Inserted 5000 rows
10. Inserted 6000 rows
11. Inserted 7000 rows
12. Inserted 8000 rows
13. Inserted 9000 rows
14. Inserted 10000 rows
15. Inserted 10000 rows into 'canceltst'.
16. Counting number of rows in 'canceltst' table...
17. Number of rows = 10000
18. Timeout interval for SQL requests is: 0.00333333 minutes
19. *** Are you ready to begin execution of the query? (y/n): y
20. Beginning execution of query...
21. +------SQL Request begins-----------------------------+
22. | |
23. +------SQL Request ends-------------------------------+
24. +------SQL Request begins-----------------------------+
25. | |
26. | An interrupt has been received by the application.|
27. | |
28. *** Do you want to confirm this interrupt? (y/n): y
29. | TIMEOUT INTERRUPT REQUESTED |
30. +------SQL Request ends-------------------------------+

=====================================================================
==

第 3 - 17 行


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

create_tbl() 函数生成这些行。它们指示函数已经成功创建 canceltst 表,
插入了 MAX_ROWS 数行(1,000),并确认 SELECT 语句可以访问行。有关
create_tbl() 函数的描述,请参阅第 262 - 281 行开头的注释。


第 18 - 19 行

第 18 行显示超时间隔来指示 sqlbreakcallback() 成功注册了回调函数,
并建立了 200
毫秒(0.00333333 分钟)的超时间隔。第 19 行询问用户以指示开始查询。此提示将为用
户提供确认提示(第 28 行和 43 行)。当数据库服务器仍在执行查询时,必须快速回复
该请求以发送中断。


第 20 行

该行指示 dspquery() 函数开始执行,数据库服务器开始执行 canceltst 查询。


第 21 - 30 行

程序输出使用消息请求框来指示客户端-服务器通信:
+------SQL Request begins-----------------------------+
| |
+------SQL Request ends-------------------------------+

每个框代表在客户端和服务器之间发送的单个消息请求。回调函数显示消息请
求框的文本。
(有关函数的哪些部分描述显示文件,
请参见第 199
-
249 行。

要执行 OPEN 语句,客户端和服务器交换了两个消息请求。输出中的两个消息
请求框指示。有关消息请求的更多信息,请参阅中断 SQL 语句。

第一个消息请求框(第 21 - 23 行)表示第一个消息请求在超时间隔过去之前完成。
第二个消息请求框(第 29 - 30 行)表示此消息请求的执行超过了超时间隔,并调用状态
值为 2 的回调函数。回调函数提示用户确认中断请求(第 28 行)。

第 29 行指示 sqlbreak() 函数已经请求中断。然后该消息请求完成(第 30 行)。

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


=================================================================
======
31. TIMEOUT INTERRUPT PROCESSED
32. *** Try another run? (y/n): y
33. Timeout interval for SQL requests is: 0.00333333 minutes
34. *** Are you ready to begin execution of the query? (y/n): y
35. Beginning execution of query...
36. +------SQL Request begins-----------------------------+
37. | |
38. +------SQL Request ends-------------------------------+
39. +------SQL Request begins-----------------------------+
40. | |
41. | An interrupt has been received by the application.|
42. | |
43. *** Do you want to confirm this interrupt? (y/n): n
44. +------SQL Request ends-------------------------------+
45. Displaying data...
46. sum(int_fld) = 25000000
47. char_fld1 = 4100 Bohannan Dr
48. char_fld2 = Menlo Park, CA
49. sum(int_fld) = 24995000
50. char_fld1 = Gbasedbt
51. char_fld2 = Software
52. Number of rows found: 2
53. *** Try another run? (y/n): n
54. Cleaning up...
55. Dropped table 'canceltst'
56. Disconnected stores7 connection
57. TIMEOUT Sample Program over.

=====================================================================
==


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

第 31 行

当数据库服务器实际处理中断请求时,它将 SQLCODE 设置为 -213。第 31 行指示
应用程序已经响应此状态。


第 32 行

此提示表示 canceltst 查询的第一次运行结束。用户第二次响应 y 到提示运行查询。



第 36 - 41 行

消息请求框指示第一个消息请求在超时间隔过去之前完成。
第二个消息请求框
(第 39
- 44 行)
指示该消息请求的执行在才超过时间间隔,
并调用回调函数
(when_called = 2)

回调函数提示用户确认中断请求(第 43 行)。这次用户回答 n。


第 45 - 52 行

因为用户没有中断 canceltst 查询,使用程序显示查询返回的行信息。


第 54 和 55 行

drop_tbl() 函数生成这些行。它们指示函数成功从数据库删除 canceltst 比
哦啊。有关 drop_tbl() 函数的描述,请参阅第 320 - 329 行开头的注释。

函数说明
返回从hour,minute,second 计算得到的时间值。
示例
示例1
返回“12,15,30”对应的时分秒的值。
gbase> SELECT MAKETIME(12,15,30) FROM t;
+--------------------+
| MAKETIME(12,15,30) |
+--------------------+
| 12:15:30 |
+--------------------+
1 row in set

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 878