返回首页

gbase数据、南大通用产品文档:GBase8s使用 IN 关键字来搜索集合中的元素

更新日期:2024年09月11日

可以在 SQL 语句的 WHERE 子句中使用 IN 关键字来确定集合是否包含某元素。例如:
下列查询显示如何构造返回 mgr_name 和 department 的值的查询,其
中 Adams 是 direct_reports 列中集合的一个元素。
图: 查询
SELECT mgr_name, department
FROM manager

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 78 -

WHERE 'Adams' IN direct_reports
图: 查询结果
mgr_name Sayles
department marketing
尽管可以使用带有 IN 关键字的 WHERE 子句来搜索简单集合中的特定集合。
但是查询总
是返回整个集合。例如:下列查询返回集合的所有元素,其中 Adams 是 direct_reports 列中
集合的一个元素。
图: 查询
SELECT mgr_name, direct_reports
FROM manager
WHERE 'Adams' IN direct_reports
图: 查询结果
mgr_name Sayles
direct_reports SET {Smith, Waters, Adams, Davis, Kurasawa}
如上所示,对集合列的查询返回整个集合,不是集合中的特定元素。
可以在 WHERE 子句中使用 IN 关键字来只引用简单集合。
不能使用 IN 关键字来引用包
含本身就是集合的字段的集合。例如:不能使用 IN 关键字来引用 manager 表中
的 projects 列,原因是 projects 是嵌套集合。
可以在 SELECT 语句的 WHERE 子句中组合 NOT 和 IN 关键字来搜索不包含某元素
的集合。例如:下列查询显示返回 mgr_name 和 department的值的查询,其中 Adams 不
是 direct_reports 列中集合的元素。
图: 查询
SELECT mgr_name, department
FROM manager
WHERE 'Adams' NOT IN direct_reports
图: 查询结果
mgr_name Williams
department engineering

mgr_name Lyman
department publications

mgr_name Cole
department accounting
有关如何对集合列中的元素进行技术的信息,请参阅基数函数。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 79 -

listen_addresses
参数说明:声明服务器侦听客户端的TCP/IP 地址。
该参数指定GBase 8c 服务器使用哪些IP 地址进行侦听,如IPV4 或IPV6(若支持)。
服务器主机上可能存在多个网卡,
每个网卡可以绑定多个IP 地址,
该参数就是控制GBase 8c
到底绑定在哪个或者哪几个IP 地址上。
而客户端则可以通过该参数中指定的IP 地址来连接
GBase 8c 或者给GBase 8c 发送请求。
该参数属于POSTMASTER 类型参数,请参考表15-15-1 中对应设置方法进行设置。
取值范围:

主机名或IP 地址,多个值之间用英文逗号分隔。

星号“*”或“0.0.0.0”表示侦听所有IP 地址。配置侦听所有IP 地址存在安全风险,不推荐
用户使用。必须与有效地址结合使用(比如本地IP 等),否则,可能造成Build 失败
的问题。
同时,
主备环境下配置为“\*”或“0.0.0.0”时,
主节点数据库路径下postgresql.conf
文件中的localport 端口号不能为数据库dataPortBase+1,否则会导致数据库无法启动。

置空则服务器不会侦听任何IP 地址,
这种情况下,
只有Unix 域套接字可以用于连接数
据库。
默认值:数据库实例安装好后,根据XML 配置文件中不同实例的IP 地址配置不同默
认值。DN 的默认参数值为:listen_addresses = 'x.x.x.x'。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1154

您可在程序中嵌入 DELETE 语句。下列示例使用 GBase 8s ESQL/C:
EXEC SQL delete from items
WHERE order_num = :onum;
您还可动态地准备和执行同样形式的语句。在任一情况下,该语句直接作用于数据库来影
响一行或多行。
示例中的 WHERE 子句使用名为 onum 的主变量的值。通常在该操作之后,将结果发布在
SQLSTATE 中以及在 sqlca 结构中。即使发生错误,SQLERRD 数组的第三个元素也包含
删除的行的计数。SQLCODE 中的值展示操作的完全成功。如果该值不是负的,则未发生
错误且 SQLERRD 的第三个元素是满足了 WHERE 子句并被删除了的所有行的计数。

直接删除期间的错误
当发生错误时,
该语句提前终止。
SQLSTATE 中的值和 SQLCODE 中的值以及 SQLERRD
的第二个元素说明它的原因,且行的计数显示删除了的行数。对于许多错误,由于错误阻
止数据库服务器开始操作,因此那个计数为零。例如,如果不存在命名的表,或如果重命
名 WHERE 子句中测试的列,则不会尝试任何删除。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司
- 231 -
然而,在操作开始且处理某些行之后,可发现某些错误。这些错误中最常见的是锁冲突。
在数据库服务器可删除那行之前,它必须获取行上的排他锁。其他程序可能正在使用来自
该表的行,阻止该数据库服务器锁定行。由于锁定的问题影响所有类型的修改,因此在 对
多用户环境编程 中讨论它。
另外,
在删除开始之后,
可出现较少见的错误类型。
例如,
在更新数据库时发生硬件错误。

事务日志记录
在修改期间为任何种类的错误做准备的最好方式是使用事务日志记录。万一发生错误,您
可告诉数据库服务器将数据库恢复原样。下列示例是基于直接删除 部分中的示例的,将其
扩展为使用事务:
EXEC SQL begin work; /* 开启事务 */
EXEC SQL delete from items
where order_num = :onum;
del_result = sqlca.sqlcode; /* 保存两个错误 */
del_isamno = sqlca.sqlerrd[1]; /* 代码编号 */
del_rowcnt = sqlca.sqlerrd[2]; /* 以及行的计数 */
if (del_result < 0) /* 发现的问题:*/
EXEC SQL rollback work; /* 恢复一切 */
else /* 一切正常:*/
EXEC SQL commit work; /* 结束事务 */
此示例中的关键在于,在程序结束该事务之前,它将重要的返回值保存在 sqlca 结构中。像
其他 SQL 语句一样,ROLLBACK WORK 和 COMMIT WORK 语句都在 sqlca 结构中设
置返回代码。
然而,
如果您想要报告错误生成的代码,
则必须在执行 ROLLBACK WORK 之
前保存它们。ROLLBACK WORK 语句移除所有暂挂的事务,包括它的错误代码。
使用事务的优势在于,不管发生什么错误,数据库都处于已知的、可预测的状态。不存在
修改完成了多少的问题;要不就是都完成了,要不就是都没完成。
在带有日志记录的数据库中,如果用户未启动一个显式的事务,则数据库服务器在语句执
行之前初始化一个内部的事务,并在执行完成或失败后终止该事务。如果语句执行成功,
则提交该内部的事务。如果语句失败,则回滚该内部的事务。

协调的删除
当您必须修改多个表时,事务日志记录的用处特别明显。例如,考虑从演示数据库删除一
个订单的问题。在该问题的最简单的形式中,您必须从两个表 orders 和 items 同时删除行,
如下列 GBase 8s ESQL/C 的示例所示:
EXEC SQL BEGIN WORK;

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司
- 232 -
EXEC SQL DELETE FROM items
WHERE order_num = :o_num;
if (SQLCODE >= 0)
{
EXEC SQL DELETE FROM orders
WHERE order_num == :o_num;
{
if (SQLCODE >= 0)
EXEC SQL COMMIT WORK;
{
else
{
printf("Error %d on DELETE", SQLCODE);
EXEC SQL ROLLBACK WORK;
}
不论是否使用事务,此程序的逻辑都很相似。如果未使用它们,则看到错误消息的人员更
难作出决定。依赖于错误发生的时间,下列情况中的一种适用:

未执行删除;此订单的所有行都保留在数据库中。

删除了某些商品行,但不是全部;仅保留某些商品的订单记录。

删除了所有商品行,但保留订单行。

删除了所有行。
在第二种和第三种情况下,数据库受到一定程度的损害;它包含可导致某些查询产生错误
结果的部分信息。您必须小心行事来恢复信息的一致性。当使用事务时,会防止所有这些
不确定性。