返回首页

gbase数据、南大通用产品文档:GBase8s与数据库服务器交互

更新日期:2024年09月11日

在 GBase 8s ESQL/C 程序中,可以用以下方式与数据库服务器交互:
启动新的数据库服务器进程。当应用程序开始执行时该进程不存在。
在多个连接之间进行切换。应用程序可以建立多个连接。
标识显式连接。应用程序可以获得数据库服务器和连接的名称。
确定当前连接的数据库服务器可以访问的数据库。
检查数据库服务器检查的状态。对于某些操作,数据库服务器必须正忙,对于其它操
作,数据库服务器必须空闲。
脱离当前连接。应用程序必须将子进程与当前进程连接。
中断数据库服务器进程。如果 SQL 请求执行了很长时间,则应用程序可以中断它。
终止数据库服务器进程。应用程序可以关闭未使用的连接以释放资源。

GBase 8s ESQL/C 支持安全套接字层(SSL)连接,有关 SSL 协议的信息,请参阅安
全套接字层协议。
确定数据库服务器的功能
可以在执行以下 SQL 语句之后检查数据库服务器的功能。
CONNECT
CREATE DATABASE
DATABASE
SET CONNECTION

当数据库服务器使用这些语句建立连接时,它可以获取有关数据库服务器的下列信息:

是长标识符还是长用户名称被截断?
打开的数据库是否使用事务日志?
打开的数据库是否符合 ANSI ?
数据库服务器的名称为?
数据库是否以 DECIMAL 格式存储 FLOAT 数据类型(当主机系统缺少对 FLOAT
类型的支持时)?
数据库服务器是否处于辅助模式?(如果数据库服务器处于辅助模式,则它是数据复

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

制对中的辅助服务器,仅可用于读取操作)?

客户端应用程序设置的 DB_LOCALE 环境变量的值是否符合打开的数据库的数据库
语言环境的值?下表总结了 SQLSTATE 变量和 sqlca 结构用于指示这些条件的值。

数据库功能
SQLSTATE 值
sqlca 值
长标识符或长用户名被截断
"01004"
sqlca.sqlwarn.sqlwarn1 是 'W'
数据库具有事务
"01I01"
sqlca.sqlwarn.sqlwarn1 是 'W'
数据库符合 ANSI
"01I03"
sqlca.sqlwarn.sqlwarn2 是 'W'
数据库服务器不是独立的产

"01I04"
sqlca.sqlwarn.sqlwarn3 是 'W'
FLOAT 作为 DECIMAL 表

"01I05"
sqlca.sqlwarn.sqlwarn4 是 'W'
数据库服务器在辅助模式
"01I06"
sqlca.sqlwarn.sqlwarn6 是 'W'
M 是符合的数据库语言环境
未定义
sqlca.sqlwarn.sqlwarn7 是 'W'

这些语句执行之后,SQLSTATE 变量可能返回多路复用异常。
在多个数据库连接中切换
GBase 8s ESQL/C 应用程序可以使用 CONNECT 语句进行多个并发的数据库连接。
这些连接可以是多个数据库环境,也可以是同一数据库环境的多个连接。要在连接之间切
换,GBase 8s ESQL/C 应用程序必须遵循以下步骤:
使用 CONNECT STATEMENT 建立连接
处理任何活动的事务

如果当前连接具有活动事务,则只有在 WITH CONCURRENT TRANSACTION 子句
的 CONNECT 语句建立当前连接时,才能切换连接。

使用 SET CONNECTION 或 CONNECT 语句建立连接
建立当前连接
当存在多个连接时,应用程序一次只能与一个连接进行通信。此连接是当前连接。所
有其他建立的连接都是休眠的。您的应用程序可以使其它连接与以下任一连接语句更新:
CONNECT 语句建立新的连接并使其成为当前连接。
SET CONNECTION 语句切换到休眠的连接并使其为当前连接。

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


当连接休眠然后再次连接时,您将执行类似于断开连接后重新连接到数据库环境的操
作。但是,如果使用连接休眠,您通常可以避免数据库服务器再次执行身份验证,从而节
省与连接相关联的资源的成本和使用。

提示: 线程安全 GBase 8s ESQL/C 应用程序具有多个当前连接。每个线程一个当前
连接。但是,一次只有一个当前连接处于活动状态。
处理事务
如果具有 WITH CONCURRENT TRANSACTION 子句的 CONNECT 语句已经建立
连接,则应用程序可以切换到另一个连接,即使当前连接包含活动的事务。

对于不是使用 CONNECT...WITH CONCURRENT TRANSACTION 语句建立的连接,
应用程序必须在它切换到另一个连接之前结束活动的事务。任何在事务处于活动状态时切
换的尝试都会导致 CONNECT 或 SET CONNECTION 语句失败(错误号 -1801)。当前
连接中的事务仍处于活动状态。

要维持数据库信息的完整性,请通过以下方式之一显式终止活动事务:
使用 COMMIT WORK 语句提交事务来确保数据库服务器保存在事务中对数据库所
做的任何更改。
使用 ROLLBACK WORK 语句回滚事务来确保数据库服务器备份在事务中对数据库
所做的任何更改。

COMMIT WORK 或 ROLLBACK WORK 语句仅适用当前连接中的事务,而不适用
于处于任何休眠连接的事务。
标识显式连接
在 GBase 8s ESQL/C 应用程序中,
您可以使用 GET DIAGNOSTICS 语句获得数据库
服务器的名称以及显式连接的名称。

当在 SQL 连接语句(CONNECT 、SET CONNECTION 和 DISCONNECT)之后使
用 GET DIAGNOSTICS 时,GET DIAGNOSTICS 键数据库服务器的信息放置到
SERVER_NAME 和 CONNECTION_NAME 字段的诊断区域。

以下代码段保存 srvrname 和 cnctname 主机变量中的连接信息。
EXEC SQL connect to :dbname;

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

if(!strncmp(SQLSTATE, "00", 2)
{
EXEC SQL get diagnostics exception 1
:srvrname = SERVER_NAME, :cnctname = CONNECTION_NAME;
printf("The name of the server is '%s'\n", srvrname);
}

在 GBase 8s ESQL/C 应用程序中。
可以使用 ifx_getcur_conn_name() 函数获得当前连
接的名称。该函数将当前连接的名称返回到用户定义的字符缓冲区。该函数可用于在具有
多个线程的 GBase 8s ESQL/C 应用程序中的一组活动的连接中确定当前连接。

例如,下列代码由一个 callback 函数 cb() 组成,它在两个不同的线程招工难使用两
个 sqlbreakcallback() 调用:
void
cb(mint status)
{
mint res;
char *curr_conn = ifx_getcur_conn_name();

if (curr_conn && strcmp(curr_conn, "con2") == 0)
{
res = sqlbreak();
printf("Return status of sqlbreak(): %d\n", res);
}
}

void
thread_1()
{
EXEC SQL BEGIN DECLARE SECTION;
mint res;
EXEC SQL END DECLARE SECTION;


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

EXEC SQL connect to 'db' as 'con1' ;
sqlbreakcallback(100, cb);
EXEC SQL SELECT count(*) INTO :res FROM x, y;
if (sqlca.sqlcode == -213)
printf("Connection con1 fired an sqlbreak().\n");
printf("con1: Result of count(*) = %d\n", res);
EXEC SQL set connection 'con1' dormant ;
}

void
thread_2()
{
EXEC SQL BEGIN DECLARE SECTION;
mint res;
EXEC SQL END DECLARE SECTION;

EXEC SQL connect to 'db' as 'con2' ;
sqlbreakcallback(100, cb);
EXEC SQL SELECT count(*) INTO :res FROM x, y;
if (sqlca.sqlcode == -213)
printf("Connection con2 fired an sqlbreak().\n");
printf("con2: Result of count(*) = %d\n", res);
EXEC SQL set connection 'con2' dormant ;
}

cb() callback 函数使用 ifx_getcur_conn_name() 检查哪个是当前连接。
获取可用的数据库
从 GBase 8s ESQL/C 应用程序中,可以使用 sqgetdbs() 函数从指定的数
据库服务器获取可用的数据库名称。该函数返回当前连接的数据库服务器中的
可用的数据库的名称。
检查数据库服务器的状态
除非数据库服务器空闲,否则数据库服务器中的某些交互不会执行。其它操作假定数
据库服务器正在忙于处理请求。可用使用 sqldone() 函数检查数据库服务器是否正在处理
SQL 请求。如果数据库服务器空闲,则该函数返回 0;如果数据库服务器忙, 则返回一

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

个负值。
为子进程建立一个单独的数据库连接
当您的应用程序推进一个进程时,子进程继承父进程的数据库连接。如果您将这些连
接保持打开状态,则父和子进程都会使用同一连接与同一数据库服务器通信。 因此,子进
程需要建立单独的数据库连接。

要为子进程建立一个单独的数据库连接:

调用 sqldetach() 将子进程从父进程中的数据库服务器连接脱离。
在子进程中建立新的连接(如果需要)。
中断 SQL 请求
要中断数据库服务器,可以使用 sqlbreak() 库函数。

有时您可能需要取消 SQL 语句。
例如,
如果不小心为长查询提供了错误的搜索条件。
您希望取消 SELECT 语句而不是等待不需要的时间。当数据库服务器执行 SQL 请求时,
GBase 8s ESQL/C 应用程序被阻断。要重新控制,应用程序必须中断 SQL 请求。

您可能出于以下原因中断 SQL 请求:
应用程序用户想要中断当前 SQL 请求。
当前 SQL 请求超出时间间隔。

重要: 应用程序必须在中断 SQL 请求后,处理任何打开的事务、游标和数据库。
中断 SQL 语句
您无法取消所有的 SQL 语句。某些类型的数据库操作不会被中断,其它的在特定的
点也不会中断。GBase 8s ESQL/C 应用程序可以中断以下 SQL 语句:
ALTER INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
EXECUTE FUNCTION
EXECUTE PROCEDURE
DELETE

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

INSERT
OPEN
SELECT
UPDATE

除了上述语句,您还可以取消循环的操作,如果它在 SPL 例程中执行。

GBase 8s ESQL/C 应用程序以及数据库服务器同消息请求通信。
消息请求是发起 SQL
任务的消息的完整往返。它可以包括应用程序发送到数据库服务器以及数据库服务器回复
的消息。或者,消息请求可以由数据库服务器向应用发送的信息以及应用程序回复的消息
组成。

大多数 SQL 语句仅需要一个消息请求来执行。应用程序将此 SQL 语句发送到数据
库服务器,数据服务器执行它。但是,传输大量数据(SELECT 、INSERT 或 PUT)SQL
语句可能需要多个消息请求执行,如下所示:
在第一个消息请求中,应用程序将 SQL 语句发送到数据库服务器执行。
在后续的消息请求中,数据库服务器使用数据填充缓冲区,然后将此数据发送到应用
程序。缓冲区的大小决定了数据库服务器在单个消息请求中发送的数据量。

此外,OPEN 语句需要两个消息请求。

数据库服务器决定何时检查中断请求。因此,数据库服务器不可能立即终止 SQL 语
句的执行,您的应用程序不可能就在它发送中断请求时就重新控制。
允许用户中断
当数据库服务器处理大数据的查询时,
您可能想要用户使用中断键
(通常为 CTRL-C)
中断查询请求。

为此,必须设置一个信号处理函数。信号处理函数是用户定义的函数,当应用程序接
收到特定的信号时应用程序进程会调用它。

要允许用户中断 SQL 请求,您要为此 SIGINT 信号定义信号处理函数。此函数必须
具有以下声明:
void sigfunc_ptr();


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

用户定义的信号处理函数可以包含 GBase 8s ESQL/C 控制函数 sqlbreak() 和
sqldone()。如果在数据库服务器正在处理时使用任何其它 GBase 8s ESQL/C 控制函数或者
信号处理程序中的任何 SQL 语句,GBase 8s ESQL/C 将生成一个错误(-439)。

GBase 8s ESQL/C 应用程序必须确定在信号处理完成后如何继续执行。一种可能的方
法是使用 setjmp() 和 longjmp() 系统函数来设置非本地化。这些函数一起工作来支持低级
中断,如下所示:
setjmp() 函数保存当前的执行环境,
然后在 longjmp() 调用之后建立一个执行返回点。

longjmp() 调用在信号处理函数。只有在 sqldone() 返回 0(数据库服务器空闲)时,
才能在信号处理函数中使用 longjmp()。

有关 setjmp() 和 longjmp() 系统函数的更多信息,请参阅 UNIX(TM) 操作系统文档。


要将用户定义的信号处理程序域系统信号相关联,请使用 signal() 系统函数,如下所
示:
signal(SIGINT, sigfunc_ptr);

当 GBase 8s ESQL/C 应用程序接收了 SIGINT 信号,
它调用 sigfunc_ptr 指示的函数。
有关 signal() 系统函数的更多信息,请参阅您的 UNIX(TM) 操作系统文件。

要从信号取消信号处理函数的关联,调用使用 SIG_DFL 作为函数指针的 signal(),
如下所示:
signal(SIGINT, SIG_DFL);

SIG_DFL 是缺省的信号处理操作。对于 SIGINT 信号,缺省操作时停止进程并生成
核心转储。您可能需要指定 SIG_IGN 操作以使应用程序忽略该信号。

重要: 在大多数系统中,信号处理程序在应用程序捕获信号后保持有效。在这些系
统上,
如果您不想在下一次捕获系统的信号时执行,
则需要将信号处理程序明确解除关联。

然而,
在几个
(大多数较旧的)
系统上,
当信号处理器捕获信号时,
系统会将 SIG_DFL
操作恢复为处理机制。在这些系统上,如果您希望在下一次捕获信号时处理相同的信号,
则信号处理程序将自动恢复。有关系统如何处理信号的信息,请查看系统文档。
设置超时间隔

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

当数据库服务器处理大量数据的查询时,您可能想要间隔地提示用户是否继续该请求。


要设置时间间隔,可以使用 sqlbreakcallback() 函数提供以下信息:
时间间隔是应用程序重新控制之前 SQL 请求等待执行的时间。
callback 函数是用户定义的函数,每次超时间隔过去都要调用。

限制: 如果您的 GBase 8s ESQL/C 应用程序使用共享内存(onipcshm)作为与数据
库服务器实例色连接中的 NETTYPE,则不要使用 sqlbreakcallback()函数。共享内存不是
真正的网络协议,
并且不处理支持回调函数所需的非阻塞 I/O 。
当您使用 sqlbreakcallback()
与共享内存时,函数调用似乎成功注册回调函数 (它返回零),但是在 SQL 请求期间,
应用程序永远不会调用回调函数。
超时间隔
使用 sqlbreakcallback() 函数,可以指定超时间隔。

超时间隔是数据库服务器在应用程序重新获得控制之前处理 SQL 请求的时间量(以
毫秒为单位)。应用程序然后调用您指定回调函数并执行完成。

回调函数完成后,应用程序将恢复其等待,直到发生以下其中一个操作:
数据库服务器将以下条件一直的控制权返回给应用程序:
它已经完成了 SQL 请求。数据库服务器返回 SQLCODE 和 SQLSTATE 变量中请
求的状态。
它语句停止处理 SQL 请求,因为它已经从回调函数中的 sqlbreak() 函数接收到中断
请求。
超过下一个超时间隔。当应用程序恢复执行时,它再次调用回调函数。
每次超时时间间隔都会调用回调函数,直到数据库服务器完成请求或中断。
回调函数
使用 sqlbreakcallback() 函数,
您还可以指定在执行 SQL 请求时在多个点调用回调函
数。

回调函数是用户定义的 GBase 8s ESQL/C 函数,
它在 SQL 语句执行期间指定要采取
的操作。该函数必须具有以下声明:
void callbackfunc(status)
mint status;

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


integerstatus 变量标识在调用回调函数的 SQL 请求执行的时间点。在回调函数中,
您可以检查此状态变量,以确定该函数在哪个是假被调用。下表总结了有效的 status 值。


表 3. 回调函数的状态值
调用回调的时间点
回调参数值
在数据库服务器语句完成 SQL 请求之后
0
紧随着应用程序将 SQL 请求发送到数据库服务器后
1
当数据库服务器正在处理 SQL 请求时,
超时间隔已过
2

在此调用函数中,您可能想要检查 status 参数的值来确定函数要采取的操作。

提示: 当您使用 sqlbreakcallback() 注册回调函数时,应用程序每次调用回调函数发
送消息请求。因此,需要多个消息请求的 SQL 语句会导致应用程序调用回调函数多次。

回调函数,以及它的子例程,只能获得以下 GBase 8s ESQL/C 控制函数:
sqldone() 库函数确定数据库服务器是否仍在忙。
如果 sqldone() 返回错误 -439,则数据库服务器仍在忙并且您可以继续执行中断。

sqlbreakcallback() 库函数将回调函数从超时间隔中解除关联。
使用以下参数调用 sqlbreakcallback():
sqlbreakcallback(-1L, (void *)NULL);

如果您希望在当前连接期间保留回调函数,则不需要此步骤。关闭当前连接时,还可
以取消关联回调函数。

sqlbreak() 库函数中断数据库服务器的执行。

如果使用任何 GBase 8s ESQL/C 控制函数而不是上述列表中的函数,或者如果您使
用任何数据库服务器正在处理的 SQL 语句,则 GBase 8s ESQL/C 生成错误(-439)。

如果应用程序调用回调函数,因为超时间隔已过,此函数可以提示用户是否继续或取
消 SQL 请求,如下所示:

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

要继续执行 SQL 请求,则回调函数略过对 sqlbreak() 的调用。
当回调函数执行时,
数据库服务器继续忽略它的 SQL 请求。
在回调函数执行完毕后,
应用程序在再次调用回调函数之前等待另一个超时间隔。在此期间,数据库服务器继续执
行 SQL 请求。

要取消此 SQL 请求,回调函数调用 sqlbreak() 函数,它将中断请求发送给数据库服
务器。
回调函数在 sqlbreak() 发送请求后立即继续执行。该应用程序不会等待数据库服务器
响应,指定它完成回调函数的执行。

当数据库服务器接收到中断请求信号时,它确定是否中断当前 SQL 请求。
如果中断,数据库服务器不会继续处理并将控制返回给应用程序。此应用程序
负责优化程序的终止;它必须释放资源并回滚当前的事务。

使用 sqlbreakcallback() 函数设置超时间隔(以毫秒为单位),然后注册回调函数,如
下所示:
sqlbreakcallback(timeout, callbackfunc_ptr);

callbackfunc_ptr 必须指向您已经定义的回调函数。在调用程序中,您必须声
明此函数,如下所示:
void callbackfunc_ptr();

重要: 在建立连接后,执行嵌入的您想要取消的 SQL 语句之前,必须注
册回调函数。在您关闭函数后,回调函数不再注册。
数据传输期间的错误检查
IFX_LOB_XFERSIZE 环境变量用于指定在检查是否发生错误之前,要从客户端应用
程序传输到数据库服务器的 CLOB 或 BLOB 中的千字节数。每次传输指定千字节的数据
时都会发生错误。如果发生错误,不会发送剩余数据并报告错误。如果没有发送错误,会
继续传输文件直到结束。
IFX_LOB_XFERSIZE 的有效服务为 1 - 9223372036854775808 KB。
IFX_LOB_XFERSIZE 环境变量在客户端上设置。
终止连接
GBase 8s ESQL/C 程序可以是以以下语句和函数关闭连接:
CLOSE DATABASE 语句关闭数据库。 CLOSE DATABASE 语句执行后,连接仍然
保持打开状态。
sqlexit() 库函数关闭所有当前连接,显式和隐式。当任何数据库仍旧打开时,如果调
用 sqlexit() ,则该函数导致任何打开的事务回滚。

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

sqldetach() 库函数关闭子进程的数据库连接。
它不会影响父进程的数据库服务器连接。

DISCONNECT 语句关闭指定的连接。如果数据库是打开的,则 DISCONNECT 语句
在它关闭连接前关闭数据库。如果事务是打开的,则 DISCONNECT 语句失败。

要创建至 GBase 8s 数据库或数据库服务器的连接,
可使用 DriverManager.getConnection() 方
法。此方法创建用于创建 SQL 语句的Connection 对象,将它们发送至 GBase 8s 数据库,
并处理结果。
DriverManager 类跟踪可用的驱动程序,并处理恰当的驱动程序与数据库或数据库服务器
之间的请求。getConnection() 方法的 url 参数是一个数据库 URL,其指定子协议(数据库
连接性机制)、数据库或数据库服务器标识符,以及属性列表。
getConnection() 方法的第二个参数 property 是属性列表。要了解如何指定属性列表的示例,
请参阅 指定属性。
下列示例展示从客户机应用程序连接至名为 testDB 的数据库 URL:
jdbc:gbasedbt-sqli://123.45.67.89:1533/testDB:

GBase 8s JDBC Driver 程序员指南
南大通用数据技术股份有限公司
- 22 -
GBASEDBTSERVER=myserver;user=rdtest;password=test
在下一部分中,描述数据库 URL 语法的详细信息。
下列来自 CreateDB.java 程序的部分示例,展示如何通过使
用 DriverManager.getConnection() 来连接至数据库 testDB。在完整的示例中,当在命令行运
行程序时,将前面示例中描述的 url 变量作为参数传递。
try
{
conn = DriverManager.getConnection(url);
}
catch (SQLException e)
{
System.out.println("ERROR: failed to connect!");
System.out.println("ERROR: " + e.getMessage());
e.printStackTrace();
return;
}
重要:
GBase 8s JDBC Driver 唯一支持的 GBase 8s 连接类型是 tcp。
不支持共享内存和其他连接
类型。要获取关于连接类型的更多信息,请参阅数据库服务器的《GBase 8s 管理员指南》。
重要: GBase 8s JDBC Driver 并不支持 Connection 接口的所有方法。要了解不受支持的方法列
表,请参阅 不支持的方法和行为不同的方法。
客户机应用程序不需要显式地关闭连接;数据库服务器自动关闭连接。然而,如果应用程
序正在使用服务器侧 JDBC 的数据库服务器中运行,则应该显式地关闭连接。

Busy Table 列表
在8s 集群节点监控导航栏,点击数据库监控的Busy Table 列表,即进入
Busy Table 列表监控界面。
该界面以列表的方式显示数据库中最忙的表的情况。
Busy Table 列表界面显示如下:

统一数据平台监控与运维系统用户手册


- 30 -

南大通用数据技术股份有限公司

双击查看某个表的详细情况,需要对数据库开启SQLTRACE,即可显示查询
该表的SQL 列表,按Max Cost 降序排列。
某表的查询SQL 列表界面显示如下: