返回首页

gbase数据、南大通用产品文档:GBase8s虚拟处理器类

更新日期:2024年09月11日

给定类的虚拟处理器只可以运行该类的线程。这些主题将描述每一类虚拟处理器执行的线
程类型或处理类型。 还将说明如何确定必须为每一类运行的虚拟处理器的数量。

CPU 虚拟处理器

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 85 -
CPU 虚拟处理器运行所有的会话线程(这些线程处理来自 SQL 客户机应用程序的请
求)和某些内部线程。内部线程执行数据库服务器的内部服务。 例如,侦听来自客户机
应用程序的连接请求的线程就是一个内部线程。
每个 CPU 虚拟处理器可以具有与之相关联的专用内存高速缓存。每个专用内存高速缓存
块由 1 到 32 个内存页组成,每个内存页大小为 4096 个字节。数据库服务器使用专用
内存高速缓存来提高对内存块的访问时间。使用 VP_MEMORY_CACHE_KB 配置参数可
启用专用内存高速缓存,并指定内存高速缓存的信息。

确定所需 CPU 虚拟处理器数
CPU 虚拟处理器的正确数量是保持繁忙(但并未繁忙到无法跟上进入的请求)的所有
CPU 虚拟处理器的数量。分配的 CPU 虚拟处理器数不得超过计算机中的硬件处理器
数。
数据库服务器启动时,除非启用了 SINGLE_CPU_VP 配置参数,否则会自动将 CPU 虚
拟处理器的数量增加到数据库服务器计算机上 CPU 处理器数量的一半。但是,可以根据
您的系统调整 CPU VP 的数量。
当数据库服务器正在运行时,要评估 CPU 虚拟处理器的性能,请在一组时间周期中以固
定的时间间隔重复以下命令:
onstat -g glo
如果将累积的 usercpu 和 syscpu 时间加在一起,将接近测试周期的 100% 实际耗用时
间,如果您让一个可用的 CPU 运行它,请添加另一个 CPU 虚拟处理器。
可使用 VPCLASS 配置参数指定以下所有信息:
• 类要最初启动的虚拟处理器数
• 类要运行的最大虚拟处理器数
• CPU 类虚拟处理器的处理器专用
• 禁用优先级迟滞(如果适用)
使用 VPCLASS 配置参数可指定此信息。(如果已从非常旧的版本升级到 GBase 8s 的当
前版本,请注意,必须使用 VPCLASS 配置参数,而不能使用已终止的 AFF_SPROC、
AFFNPROCS、NOAGE、NUMCPUVPS 和 NUMAIOVPS 配置参数。此外,不能将
VPCLASS 参数与已终止的参数结合使用。例如,如果 onconfig 文件包含 NUMCPUVPS
参数,并且还包含 VPCLASS cpu 参数,那么您将接收到错误消息。)

在多处理器计算机上运行
如果您要在多处理器计算机上运行多个 CPU 虚拟处理器,请将 onconfig 文件中的
MULTIPROCESSOR 参数设置为 1。在将 MULTIPROCESSOR 设置为 1 时,数据库服
务器将按适合多处理器计算机的方式执行锁定。有关设置多处理器方式的信息,请参阅
《GBase 8s 管理员参考》中有关配置参数的章节。


GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 86 -
在单处理器计算机上运行
如果您正在单个处理器计算机上运行数据库服务器,请将 MULTIPROCESSOR 配置参数
设置为 0。 要运行只具有一个 CPU 虚拟处理器的数据库服务器,请将
SINGLE_CPU_VP 参数设置为 1。
将 MULTIPROCESSOR 设置为 0 可使数据库服务器绕过多处理器计算机上多个处理器
所需的锁定。有关 MULTIPROCESSOR 配置参数的信息,请参阅《GBase 8s 管理员参
考》。
将 SINGLE_CPU_VP 设置为 1 允许数据库服务器绕过某些互斥调用,这些互斥调用通常
在运行多个 CPU 虚拟处理器时建立。有关设置 SINGLE_CPU_VP 参数的信息,请参阅
《GBase 8s 管理员参考》。
重要: 将 VPCLASS num 设置为 1 并将 SINGLE_CPU_VP 设置为 0 不会减少互斥调用的
数量,即使数据库服务器仅启动一个 CPU 虚拟处理器。必须将 SINGLE_CPU_VP 设置为 1
以减少当您运行单个 CPU 虚拟处理器时执行的锁存器的量。
将 SINGLE_CPU_VP 参数设置为 1 会对数据库服务器施加两个重要限制,如下所示:
• 只允许一个 CPU 虚拟处理器。
当数据库服务器是联机方式时,不能添加 CPU 虚拟处理器。
• 不允许任何用户定义的类。(但是,用户仍然可以定义直接运行在 CPU VP 上的
例程。)
有关更多信息,请参阅在联机方式下添加虚拟处理器。

在联机方式下添加和删除 CPU 虚拟处理器
当数据库服务器是联机方式时,您可以添加或删除 CPU 类虚拟处理器。有关如何进行这
些操作的指示信息,请参阅在联机方式下添加虚拟处理器和删除 CPU 和用户定义的虚拟
处理器。

阻止优先级迟滞
有些操作系统将在累积处理时间时降低长时间运行的进程的优先级。操作系统的这种功能
称为优先级迟滞。优先级迟滞可以导致数据库服务器进程的性能随着时间的流逝而降低。
然而,在有些情况下,可使用操作系统禁用此功能并且将长时间运行的进程保持在高优先
级中运行。
要确定优先级迟滞是否在您的计算机上可用,请检查在本指南『简介』中描述的安装随附
的机器说明文件。
如果可通过操作系统禁用优先级迟滞,那么可以在 VPCLASS 配置参数中为优先级条目
指定 noage 来禁用该功能。有关更多信息,请参阅《GBase 8s 管理员参考》。

处理器亲缘关系

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 87 -
数据库服务器支持将 CPU 虚拟处理器自动绑定到支持处理器亲缘关系的多处理器计算机
上的处理器。您的数据库服务器分发手册将包含机器说明文件,该文件包含有关您的数据
库服务器是否支持此功能的信息。当您将 CPU 虚拟处理器指定给特定 CPU 时,虚拟处
理器只运行在该 CPU 上,但是其他进程也可以运行在该 CPU 上。
使用带有 aff 选项的 VPCLASS 配置参数可在支持它的多处理器计算机上实现处理器专
用。
下图说明了处理器亲缘关系的概念。
图: 处理器亲缘关系


仅限 UNIX: 要查看 UNIX™ 平台上是否支持处理器亲缘关系,请参阅机器说明文件。

使用 VPCLASS 配置参数设置处理器亲缘关系
要使用 VPCLASS 配置参数设置处理器亲缘关系,可以指定要为其指定虚拟处理器的单
个处理器或某一范围的处理器。指定某一范围处理器时,还可以指定范围内的递增值,用
于指示将范围中的哪些 CPU 指定给虚拟处理器。例如,可以指定将虚拟处理器分配给范
围 0-6 中的每隔一个 CPU,从 CPU 0 开始。
VPCLASS CPU,num=4,aff=(0-6/2)
虚拟处理器分配给 CPU 0、2、4、6。
如果指定 VPCLASS CPU,num=4,aff=(1-10/3),将虚拟处理器分配给范围 1-10 中的每隔两
个 CPU,从 CPU 1 开始。虚拟处理器分配给 CPU 1、4、7、10。
指定多个值或范围时,这些值和范围不必是递增的,也无需按照任何特定顺序指定。例
如,可以指定 aff=(8,12,7-9,0-6/2)。
数据库服务器将 CPU 虚拟处理器分配给循环模式中的 CPU,从您在 aff 选项中指定的
第一个处理器编号开始。如果指定的 CPU 虚拟处理器数多于实际的 CPU 数量,那么数
据库服务器继续从首个 CPU 开始分配 CPU 虚拟处理器。例如,假设您指定了以下
VPCLASS 设置:
VPCLASS cpu,num=8,aff=(4-7)
数据库服务器会进行以下分配:

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 88 -
• CPU 虚拟处理器编号 0 到 CPU 4
• CPU 虚拟处理器编号 1 到 CPU 5
• CPU 虚拟处理器编号 2 到 CPU 6
• CPU 虚拟处理器编号 3 到 CPU 7
• CPU 虚拟处理器编号 4 到 CPU 4
• CPU 虚拟处理器编号 5 到 CPU 5
• CPU 虚拟处理器编号 6 到 CPU 6
• CPU 虚拟处理器编号 7 到 CPU 7
有关更多信息,请参阅《GBase 8s 管理员参考》中的 VPCLASS 配置参数。

用户定义的虚拟处理器类
可以定义特殊的虚拟处理器类以运行用户定义的例程。通常可编写用户定义的例程以支持
用户定义的数据类型。 如果您不想要用户定义的例程运行在 CPU 类(这是缺省值)
中,那么您可以将它指定给虚拟处理器 (VP) 的用户定义类。用户定义的虚拟处理器类还
称为扩展虚拟处理器。
这些主题提供了以下有关用户定义的虚拟处理器的信息:
• 何时在用户定义的 VP 而不是 CPU VP 中运行 C 语言 UDR
• 如何将 C 语言 UDR 指定给一个特定的用户定义 VP 类
• 当数据库服务器处于联机方式时,如何添加和删除用户定义的 VP
确定所需的用户定义的虚拟处理器数
可以指定操作系统允许的任意数量的用户定义虚拟处理器。如果运行许多 UDR 或带有
UDR 的并行 PDQ 查询,那么必须配置多个用户定义的虚拟处理器。

用户定义的虚拟处理器
用户定义的虚拟处理器类可保护数据库服务器免遭行为不良的用户定义例程的破坏。行为
不良的用户定义的例程至少有以下特征之一:
• 不会为其他线程让出控制权
• 进行分块操作系统调用
• 修改全局 VP 状态
行为良好的 C 语言 UDR 不具有这些特征。 仅在 CPU VP 中运行行为良好的 C 语言
UDR。
警告: 在 CPU VP 中执行行为不良的例程会导致对数据库服务器操作的严重干扰,并且可能
导致其失败或行为反常。此外,例程本身可能不会产生正确的结果。
要确保安全执行,将任何行为不良的用户定义的例程指定给用户定义的虚拟处理器类。
用户定义的 VP 除去 CPU VP 类上的以下编程限制:
• 需要定期让出处理器
• 需要终止阻塞 I/O 调用

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 89 -
在用户定义的虚拟处理器类中运行的函数无需让出处理器,并且它们可能发出直接的文件
系统调用,用于阻止虚拟处理器的进一步处理,直到 I/O 完成。
用户查询的正常处理不受 C 语言 UDR 不良行为的影响,因为这些 UDR 不在 CPU 虚
拟处理器中执行。

指定用户定义的虚拟处理器
带有 vpclass 选项的 VPCLASS 参数定义用户定义的 VP 类。还可以指定非让步的用户
定义的虚拟处理器。有关更多信息,请参阅指定虚拟处理器类和《GBase 8s 管理员参
考》中有关配置参数的主题。

将 UDR 指定给用户定义的虚拟处理器类
SQL CREATE FUNCTION 语句注册用户定义的例程。例如,以下 CREATE FUNCTION
语句注册用户定义的例程 GreaterThanEqual(),并指定对于该例程的调用由名为 UDR 的
用户定义的 VP 类执行:
CREATE FUNCTION GreaterThanEqual(ScottishName, ScottishName)
RETURNS boolean
WITH (CLASS = UDR )
EXTERNAL NAME ‘/usr/lib/objects/udrs.so'
LANGUAGE C
要执行该函数,onconfig 文件必须包含定义 UDR 类的 VPCLASS 参数。否则,对
GreaterThanEqual 函数的调用将失败。
提示: CLASS 例程修饰符可为 VP 类指定任何名称。注册 UDR 时,无需有该类名。
然而,尝试运行 UDR 且其指定了用于执行的用户定义 VP 类时,此类必须存在并且必
须为其指定虚拟处理器。
要配置 UDR 类,请在 onconfig 文件中包含如下类似行。此行将配置带有两个虚拟处理
器并且没有优先级迟滞的 UDR 类。
VPCLASS UDR ,num=2,noage
前面的行将 UDR VP 类定义为生成的 VP 类;即该 VP 类允许 C 语言 UDR 生成必须
访问 UDR VP 类的其他线程。有关如何使用 VPCLASS 配置参数的更多信息,请参阅
《GBase 8s 管理员参考》。
有关 CREATE FUNCTION 语句的更多信息,请参阅《GBase 8s SQL 指南:语法》。

在联机方式下添加和删除用户定义的虚拟处理器
可以在数据库服务器处于联机状态时添加或删除用户定义的类中的虚拟处理器。有关如何
进行这些操作的指示信息,请参阅在联机方式下添加虚拟处理器和删除 CPU 和用户定义
的虚拟处理器。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 90 -

Java 虚拟处理器
Java™ UDR 和 Java 应用程序在专门的虚拟处理器(称为 Java 虚拟处理器 (JVP))上运
行。JVP 在其代码中嵌入 Java 虚拟机 (JVM)。JVP 与 CPU VP 具有相同的功能,CPU
VP 可以处理所有的 SQL 查询。
可以指定操作系统允许的任意数量的 JVP。如果运行许多 Java 或带有 Java UDR 的并行
PDQ 查询,那么必须配置更多 JVP。
使用带有 jvp 关键字的 VPCLASS 配置参数可配置 JVP。有关更多信息,请参阅
《GBase 8s 管理员参考》中的配置参数章节。

磁盘 I/O 虚拟处理器
以下虚拟处理器的类执行磁盘 I/O:
• PIO(物理日志 I/O)
• LIO(逻辑日志 I/O)
• AIO(异步 I/O)
• CPU(内核异步 I/O)
除非物理日志文件和逻辑日志文件位于原始磁盘空间中,并且数据库服务器已实现
KAIO,否则 PIO 类将执行所有到物理日志文件的 I/O,而 LIO 类执行所有到逻辑日志
文件的 I/O。
在不支持 KAIO 的操作系统上,数据库服务器使用虚拟处理器的 AIO 类来执行与物理或
逻辑日志记录不相关的数据库 I/O。
当 KAIO 可用于平台时,数据库服务器使用 CPU 类来执行 KAIO。如果数据库服务器
实现 KAIO,那么 KAIO 线程对原始的磁盘空间执行所有的 I/O,包括物理日志和逻辑
日志的 I/O。
仅限 UNIX: 要了解您的 UNIX™ 平台是否支持 KAIO,请参阅机器说明文件。
有关非日志记录 I/O 的更多信息,请参阅异步的 I/O。

I/O 优先级
一般来说,数据库服务器通过将不同类型的 I/O 指定给虚拟处理器的不同类,并将优先
级指定给非日志记录 I/O 队列来划分磁盘 I/O 的优先级。例如,划分优先级可确保高优
先级日志 I/O 绝不会排列在对临时文件进行写操作的后面,该写操作具有低优先级。数
据库服务器会对于其执行的不同类型的磁盘 I/O 划分优先级,如下表所示。
表 1. 数据库服务器为磁盘 I/O 划分优先级的方法
优先级
I/O 类型
VP 类
第 1 级
逻辑日志 I/O
CPU 或 LIO
第 2 级
物理日志 I/O
CPU 或 PIO

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 91 -
优先级
I/O 类型
VP 类
第 3 级
数据库 I/O
CPU 或 AIO
第 3 级
页清除 I/O
CPU 或 AIO
第 3 级
预读取 I/O
CPU 或 AIO

逻辑日志 I/O
虚拟处理器的 LIO 类对以下情况中的逻辑日志文件执行 I/O:
• 没有实现 KAIO。
• 逻辑日志文件位于熟磁盘空间。
仅当实现了 KAIO 并且逻辑日志文件在原始的磁盘空间中时,数据库服务器才会使用
CPU 虚拟处理器中的 KAIO 线程来对逻辑日志执行 I/O。
逻辑日志文件将存储使数据库服务器能够回滚事务并从系统故障中恢复的数据。对逻辑日
志文件的 I/O 是数据库服务器执行的最高优先级的磁盘 I/O。
如果逻辑日志文件存在于非镜像的数据库空间中,那么数据库服务器只运行一个 LIO 虚
拟处理器。如果逻辑日志文件存在于镜像的数据库空间中,那么数据库服务器运行两个
LIO 虚拟处理器。此虚拟处理器类没有任何与其关联的参数。

物理日志 I/O
虚拟处理器的 PIO 类对以下情况中的物理日志文件执行 I/O:
• 没有实现 KAIO。
• 物理日志文件存储在已缓冲的文件块中。
仅当实现了 KAIO 并且物理日志文件存在于原始的磁盘空间中时,数据库服务器才会使
用 CPU 虚拟处理器中的 KAIO 线程来对物理日志执行 I/O。物理日志文件将存储自上一
个检查点以来已更改的数据库空间页的前映像。(有关检查点的更多信息,请参阅检查
点。)在恢复开始时,数据库服务器会在处理来自逻辑日志的事务前,使用物理日志文件
将前映像复原到自上一个检查点以来已更改的数据库空间页。对物理日志文件的 I/O 是
继对逻辑日志文件的 I/O 之后第二高的优先级 I/O。
如果物理日志文件存在于非镜像的数据库空间中,那么数据库服务器只运行一个 PIO 虚
拟处理器。 如果物理日志文件存在于镜像的数据库空间中,那么数据库服务器运行两个
PIO 虚拟处理器。此虚拟处理器类没有任何与其关联的参数。

异步的 I/O
数据库服务器异步执行数据库 I/O,这意味着 I/O 将独立于请求 I/O 的线程进行排列和
执行。异步地执行 I/O 允许建立请求的线程当 I/O 正在执行时继续工作。
数据库服务器使用以下某个设施异步执行所有的数据库 I/O:
• AIO 虚拟处理器
• 平台(该平台支持 KAIO)上的 KAIO

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 92 -
数据库 I/O 包含 SQL 语句的 I/O、预读 I/O、页清除 I/O 以及检查点 I/O。

内核异步 I/O
当以下条件存在时,数据库服务器使用 KAIO:
• 计算机和操作系统对其支持。
• 已实现性能提高。
• I/O 是对于原始的磁盘空间的。
数据库服务器通过在 COU 虚拟处理器上运行 KAIO 线程来实现 KAIO。KAIO 线程通
过建立对操作系统(该操作系统可执行独立于虚拟处理器的 I/O)的系统调用来执行
I/O。KAIO 线程能够对于磁盘 I/O 产生比 AIO 虚拟处理器产生的更好的性能,因为该
线程不需要在 CPU 和 AIO 虚拟处理器之间切换。
仅限 UNIX: 当 GBase 8s 具有支持此功能的平台的端口时,GBase 8s 将实现 KAIO。
数据库服务器管理员不用配置 KAIO。要查看 KAIO 是否在您的平台上受支持,请参阅
机器说明文件。
仅限 Linux: 内核异步 I/O (KAIO) 在缺省情况下启用。 您可以通过在启动服务器的进
程环境中指定 KAIOOFF=1 来禁用内核异步 I/O。
在 Linux™ 上,并行 KAIO 请求具有最大数量的系统范围限制。/proc/sys/fs/aio-max-nr 文
件包含该值。Linux™ 系统管理员可以增加该值,例如,通过使用该命令:
# echo new_value > /proc/sys/fs/aio-max-nr
所有操作系统进程的已分配请求的当前数量在 /proc/sys/fs/aio-nr 文件中可见。
在缺省情况下,Datebse Server 分配请求的最大数量的一半,并将它们同样分配给已配置
CPU 虚拟处理器的数量。 您可以使用环境变量 KAIOON 来控制分配给每个 CPU 虚拟
处理器的请求数量。在启动 GBase 8s 之前,通过将 KAIOON 设置为必需值来执行此操
作。
KAIOON 的最小值是 100。如果 Linux 即将耗尽 KAIO 资源,例如当动态地添加许多
CPU 虚拟处理器时,online.log 文件中将打印警告。如果发生了此情况,那么 Linux 系
统管理员必须按照上述方式添加 KAIO 资源。

AIO 虚拟处理器
如果平台不支持 KAIO 或如果 I/O 是缓冲区文件块,那么数据库服务器将通过虚拟处理
器的 AIO 类执行数据库 I/O。所有的 AIO 虚拟处理器同等服务其类中的所有 I/O 请
求。
数据库服务器将根据块的文件名为每个磁盘块指定一个队列(有时称为 gfd 队列)。数
据库服务器根据最小化磁头移动算法预订队列中的 I/O 请求。AIO 虚拟处理器为工作在
循环法方式下暂挂的队列提供服务。
所有其他的非阻塞 I/O 排列在 AIO 队列中。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 93 -
使用带有 aio 关键字的 VPCLASS 参数可指定数据库服务器初次启动的 AIO 虚拟处理
器的数量。有关 VPCLASS 的信息,请参阅《GBase 8s 管理员参考》中有关配置参数的
章节。
当数据库服务器是联机方式时,您可以启动其他的 AIO 虚拟处理器。有关更多信息,请
参阅在联机方式下添加虚拟处理器。
当数据库服务器处于联机方式时,您不能删除 AIO 虚拟处理器。

自动增加和降低 AIO 虚拟处理器的数量
当服务器检测到 AIO VP 的处理速度跟不上 I/O 工作负载时,AUTO_AIOVPS 配置参数
启用或禁用数据库服务器自动增加 AIO VP 和 flusher 线程的数目。如果您想要手动调整
该数值,请禁用此参数。有关设置减少此参数的详细信息,请参阅《GBase 8s 管理员参
考》。

所需的 AIO 虚拟处理器数
分配 AIO 虚拟处理器的目的是分配足够的虚拟处理器从而可以保持 I/O 请求队列的长度
比较短;即,队列中具有的 I/O 请求要尽可能少。当 gfd 队列总是很短时,它指示对于
磁盘设备的 I/O 正在以与产生请求一样快的速度进行处理。
onstat-g ioq 命令显示了有关 I/O 队列的长度和其他统计信息。可以使用此命令为 AIO
虚拟处理器监视 gfd 队列的长度。
一个 AIO 虚拟处理器可能已足够:

如果数据库服务器在您的平台上实现内核异步 I/O (KAIO) 并且所有的数据库空
间都是由原始的磁盘空间组成。

如果您的文件系统支持用于数据库空间块的页大小的直接 I/O 并且您使用直接 I/O
对每个活动的数据库空间分配两个由缓冲区文件块组成的 AIO 虚拟处理器。
• 如果数据库服务器实现 KAIO,但是您正在使用块的某些缓冲区文件
• 如果系统不支持块的 KAIO。
如果 KAIO 不在您的平台上实现,请为数据库服务器经常访问的每个磁盘分配两个 AIO
虚拟处理器。
如果您使用熟文件,并且如果您使用 DIRECT_IO 配置参数启用直接 I/O,那么您可能可
以减少 AIO 虚拟处理器的数量。
如果数据库服务器实现了 KAIO 并且使用 DIRECT_IO 配置参数启用了直接 I/O,那么
GBase 8s 将尝试使用 KAIO,这样可能就不需要多个 AIO 虚拟处理器。 但是,即使启
用了直接 I/O,如果文件系统不支持直接 I/O 或 KAIO,那么仍必须为组成已缓冲文件块
或不使用 KAIO 的每个活动的数据库空间分配两个 AIO 虚拟处理器。
临时数据库空间不使用直接 I/O。如果您拥有临时数据库空间,那么可能需要多个 AIO
虚拟处理器。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 94 -
分配足够的 AIO 虚拟处理器以满足 I/O 请求的最大值。通常来说,分配过多的 AIO 虚
拟处理器不会产生不利影响。
当服务器检测到 AIO 虚拟处理器无法满足 I/O 工作负载时,AUTO_AIOVPS 配置参数
可使数据库服务器自动增加 AIO 虚拟处理器和 page-cleaner 线程的数量。

网络虚拟处理器
如客户机/服务器通信中所述,客户机可以下列方式连接到数据库服务器:
• 通过网络连接
• 通过管道
• 通过共享内存
网络连接可以由远程计算机上的客户机建立,或由本地计算机上的客户机通过模拟来自远
程计算机的连接(称为本地回送连接)建立。

指定网络连接
通常来说,DBSERVERNAME 和 DBSERVERALIASES 参数定义在 sqlhosts 文件或注册
表中具有对应条目的 dbservername。sqlhosts 中的每个 dbservername 都有指定接口/协议
组合的 nettype 条目。数据库服务器为每个唯一的 nettype 条目运行一个或多个轮询线
程。
NETTYPE 配置参数为接口/协议组合提供可选配置信息。可以将其用于为接口/协议组合
指定多个轮询线程,也可用于指定运行轮询线程的虚拟处理器类(CPU 或 NET)。
有关 NETTYPE 配置参数的完整描述,请参阅《GBase 8s 管理员参考》。

在 CPU 或网络虚拟处理器上运行轮询线程
轮询线程可以在 CPU 虚拟处理器或网络虚拟处理器上运行。通常来说,特别在单个处理
器计算机上,轮询线程在 CPU 虚拟处理器上的运行更加高效。然而,在具有大量远程客
户机的多处理器计算机上,这种情况可能并不成立。
NETTYPE 参数具有名为 vp class 的可选条目,可用于指定 CPU 或 NET 以分别表示
CPU 或网络虚拟处理器类。
如果没有为与 DBSERVERNAME 变量关联的接口/协议组合(轮询线程)指定虚拟处理
器类,该类将缺省为 CPU。数据库服务器假设与 DBSERVERNAME 关联的接口/协议组
合是效率最高的主接口/协议组合。
对于其他的接口/协议组合,如果没有指定 vp class,那么缺省值将是 NET。
当数据库服务器处于联机方式时,您无法删除正在运行轮询或侦听线程的 CPU 虚拟处理
器。
重要: 必须仔细区分用于网络连接的轮询线程和用于共享内存连接的轮询线程,后者在每个
CPU 虚拟处理器上只能运行一个。TCP 连接必须仅处于网络虚拟处理器中,并且您必须只有
维持响应所需的最少的 TCP 连接数。共享内存连接必须仅处于 CPU 虚拟处理器中,并在每

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 95 -
个 CPU 虚拟处理器中运行。

指定联网虚拟处理器数
每个轮询线程需要单独的虚拟处理器,因此当您为接口/协议组合指定轮询线程数量时,您
将间接地指定连网虚拟处理器的数量并指定这些处理器将由 NET 类运行。如果您为 vp
class 指定 CPU 时,您必须分配一个足够大数量的 CPU 虚拟处理器以运行轮询线程。
如果数据库服务器没有使 CPU 虚拟处理器运行 CPU 轮询线程,它将启动指定类的网络
虚拟处理器运行轮询线程。
对于大多数系统,每个接口/协议组合有一个轮询线程以及一个虚拟处理器就足够了。对于
具有 200 或更多网络用户的系统,运行额外的网络虚拟处理器可能提高吞吐量。在这种
情况下,必须进行实验以便确定每个接口/协议组合的最佳虚拟处理器数。

为客户机/服务器连接指定侦听和轮询线程
启动数据库服务器时,oninit 进程将为使用 onconfig 文件中的 DBSERVERNAME 和
DBSERVERALIASES 参数指定的每个 dbservername 启动内部线程,这些线程称为侦听
线程。要为这些数据库服务器名条目中的每一个指定侦听端口,请在 sqlhosts 中为其指
定 hostname 和 service name 条目的唯一组合。例如,下表中显示的 sqlhosts 文件条目
或注册表项将使数据库服务器 soc_ol1 为主机或网络地址 myhost 上的 port1 启动侦听
线程。
表 1. 每个侦听端口的侦听线程
dbservername
nettype
hostname
服务名
soc_ol1
onsoctcp
myhost
port1
侦听线程打开端口并请求指定接口/协议组合的轮询线程之一监视客户机请求的端口。轮询
线程为正在使用的连接运行于 CPU 虚拟处理器或网络虚拟处理器中。有关轮询线程数的
信息,请参阅指定联网虚拟处理器数。
有关如何指定接口/协议组合的轮询线程是在 CPU 虚拟处理器中运行还是在网络虚拟处理
器中运行的信息,请参阅在 CPU 或网络虚拟处理器上运行轮询线程以及《GBase 8s 管理
员参考》中的 NETTYPE 配置参数。
当轮询线程从客户机接收到连接请求,它会将请求传递给该端口的侦听线程。侦听线程将
认证用户,建立到数据库服务器的连接,然后启动 sqlexec 线程,该线程是为客户机执行
主处理的会话线程。下图说明了侦听线程和轮询线程在建立与客户机应用程序的连接时的
角色。
图: 轮询线程和侦听线程在与客户机连接时的角色


GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 96 -

轮询线程等待来自客户机的请求,并将这些请求放在共享内存以便由sqlexec 线程处理。
对于网络连接,轮询线程将消息放在共享内存全局池中的队列中。然后,轮询线程将唤醒
客户机的 sqlexec 线程以处理该请求。只要可能,sqlexec 线程都会直接写回客户机而无
需轮询线程的帮助。通常,轮询线程从客户机读取数据,然后 sqlexec 线程将数据发送到
客户机。
仅限 UNIX: 对于共享内存连接,轮询线程将该消息放在共享内存的通信部分中。
下图说明了轮询线程和 sqlexec 线程在与客户机应用程序通信时执行的基本任务。
图: 轮询线程和 sqlexec 线程在与客户机应用程序通信时的角色


GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 97 -


快速轮询
如果操作系统平台支持快速轮询,那么使用 FASTPOLL 配置参数可启用或禁用网络的快
速轮询。如果有大量连接,快速轮询会很有用。例如,如果数据库服务器具有 300 多个
并行连接,那么可以启用 FASTPOLL 配置参数以获取更好的性能。可通过将
FASTPOLL 配置参数设置为 1 来启用快速轮询。
如果您的操作系统不支持快速轮询,GBase 8s 将忽略 FASTPOLL 配置参数。

多个侦听线程
可以通过使用多个侦听线程来提高连接请求的服务。
如果数据库服务器无法为带有单个端口和相应侦听线程的给定接口/协议组合提供令人满意
的连接请求服务,那么可以通过以下方法改进对连接请求的服务:
• 为其他端口添加侦听线程。
• 向同一个端口添加侦听线程(前提是有 onimcsoc 或 onsoctcp 协议)
• 再添加一块网络接口卡。
• 通过使用 SQL 管理 API 或 onmode -P 命令,动态启动、停止或重新启动
SOCTCP 或 TLITCP 网络协议的侦听线程。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 98 -
如果 onsoctcp 协议的一个端口有多个侦听线程,并且 CPU VP 连接正忙,那么数据库服
务器可以接受新连接。

添加侦听线程
启动数据库服务器时,oninit 进程将为具有使用 DBSERVERNAME 和
DBSERVERALIASES 配置参数指定的服务器名称和服务器别名的服务器启动侦听线程。
可以为其他端口添加侦听线程。
还可以为 onimcsoc 或 onsoctcp 的一个服务(端口)设置多个侦听线程。
要为附加端口添加侦听线程,您必须首先使用 DBSERVERALIASES 参数来指定每个端
口的 dbservername。例如,下图中 DBSERVERALIASES 参数为标识为 soc_ol1 的数据
库服务器实例另外定义了两个 dbservername:soc_ol2 和 soc_ol3。
DBSERVERNAME soc_ol1
DBSERVERALIASES soc_ol2,soc_ol3
为数据库服务器定义了其他 dbservername 之后,必须在 sqlhosts 文件或注册表中为每个
dbservername 指定接口/协议组合与端口。每个端口将由 hostname 和 servicename 条目
的唯一组合标识。 例如,下表中显示的 sqlhosts 条目会使数据库服务器为 onsoctcp 接
口/协议组合启动三个侦听线程,每个定义的端口一个线程。
表 1. 要侦听单个接口/协议组合的多个端口的 sqlhosts 条目
dbservername
nettype
hostname
服务名
soc_ol1
onsoctcp
myhost
port1
soc_ol2
onsoctcp
myhost
port2
soc_ol3
onsoctcp
myhost
port3
如果包含了接口/协议组合的 NETTYPE 参数,它将应用于接口/协议组合的所有连接。
换句话说,如果上表中存在 onsoctcp 的 NETTYPE 参数,那么该参数将应用于所有显示
的连接。在本例中,数据库服务器为 onsoctcp 接口/协议组合运行一个轮询线程,直到指
定了更多的 NETTYPE 参数。有关 sqlhosts 文件中的条目或注册表中的项的更多信息,
请参阅连接文件。
为 onimcsoc 或 onsoctcp 协议的一个端口设置多个侦听线程
要为 onimcsoc 或 onsoctcp 协议的一个服务(端口)设置多个侦听线程,请执行以下操
作:
• DBSERVERNAME -
• DBSERVERALIASES -,
例如:
• 要为 DBSERVERNAME 为 ifx 的服务器启用两个侦听线程,请指定:
DBSERVERNAME ifx-2

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 99 -
• 要为 DBSERVERALIASES 为 ifx_a 和 ifx_b 的服务器启用两个侦听线程,
请指定:
DBSERVERALIASES ifx_a-2,ifx_b-2

添加网络接口卡
可以添加网络接口卡来提高性能或将数据库服务器连接到多个网络。
如果主机的网络接口卡无法提供令人满意的连接请求服务,您可能希望提高性能。
要支持多块网络接口卡,您必须在 sqlhosts 中为每块卡指定一个唯一的主机名(网络地
址)。
例如,通过使用添加侦听线程中显示的同一个 dbservernames,下表中显示的 sqlhosts 文
件条目或注册表项将使数据库服务器为相同接口/协议组合启动三个侦听线程(如添加侦听
线程中的条目所执行的操作)。 但是,在此情况下,两个线程要侦听一个接口卡
(myhost1) 上的端口,而第三个线程要侦听第二个接口卡 (myhost2) 上的端口。
表 1. 为 onsoctcp 接口/协议组合的两块网络接口卡提供支持的 sqlhosts 条目示例
dbservername
nettype
hostname
服务名
soc_ol1
onsoctcp
myhost1
port1
soc_ol2
onsoctcp
myhost1
port2
soc_ol3
onsoctcp
myhost2
port1

动态启动、停止或重新启动侦听线程
可以为 SOCTCP 或 TLITCP 网络协议动态启动、停止或停止并启动侦听线程,而不必中
断现有连接。 例如,您可能希望停止不响应的侦听线程,然后启动新侦听线程,而同时
不希望关闭其他正在正常执行的服务器。
侦听线程必须在服务器的 sqlhosts 文件中定义。如有必要,可在启动、停止或重新启动侦
听线程之前,修改 sqlhosts 条目。
要动态启动、停止或重新启动侦听线程,请执行以下操作:
1. 运行以下某个 onmode -P 命令:
o
onmode -P start server_name
o
onmode -P stop server_name
o
onmode -P restart server_name
2. 此外,如果已直接或远程连接到 sysadmin 数据库,那么可运行以下某个命令:
o
带 start listen 自变量的 admin() 或 task() 命令,格式如下
EXECUTE FUNCTION task("start listen", "server_name");
o
带 stop listen 自变量的 admin() 或 task() 命令,格式如下
EXECUTE FUNCTION task("stop listen" ,"server_name");
o
带 restart listen 自变量的 admin() 或 task() 命令,格式如下

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 100 -
EXECUTE FUNCTION task("restart listen", "server_name");
例如,以下任一命令均为名为 ifx_serv2 的服务器启动新侦听线程:
onmode -P start ifx_serv2
EXECUTE FUNCTION task("start listen", "ifx_serv2");

通信支持模块虚拟处理器
虚拟处理器的通信支持模块 (CSM) 类执行通信支持服务和通信支持模块函数。
除非将通信支持模块设置为 GSSCSM 来支持单点登录,否则数据库服务器会启动与
CPU 虚拟处理器启动数量相同的 CSM 虚拟处理器。如果通信支持模块为 GSSCSM,数
据库服务器将仅启动一个 CSM 虚拟处理器。
有关通信支持服务的更多信息,请参阅客户机/服务器通信。

加密虚拟处理器
如果没有在 onconfig 配置文件中定义 VPCLASS 参数的 encrypt 选项,那么在首次调用
为列级别加密定义的任何加密或解密功能时,数据库服务器将启动一个 ENCRYPT VP。
您可以根据需要定义多个 ENCRYPT VP 以缩短启动数据库服务器所需的时间。
使用带有 encrypt 关键字的 VPCLASS 配置参数可配置加密 VP。例如,要添加 5 个
ENCRYPT VP,请如下所示在 onconfig 文件中添加信息:
VPCLASS encrypt,num=5
您可使用 onmode 实用程序修改相同的信息,如下所示:
onmode -p 5 encrypt
有关更多信息,请参阅《GBase 8s 管理员参考》中的配置参数和 onmode 实用程序主
题。

光虚拟处理器
虚拟处理器的可选类 (OPT) 仅与 Optical Subsystem 一起使用。如果 STAGEBLOB 配置
参数存在,那么 Optical Subsystem 在可选类中启动一个虚拟处理器。

审计虚拟处理器
通过将 onconfig 文件中的 ADTMODE 参数设置为 1 来打开审计方式时,数据库服务器
将启动审计类 (ADT) 中的一个虚拟处理器。

综合性虚拟处理器

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 101 -
综合性虚拟处理器将为系统调用的请求(如获取有关当前用户或主机系统名的信息)提供
服务,这些系统调用可能需要非常大的堆栈。此虚拟处理器上只可运行一个线程;该线程
将通过 128 KB 的堆栈执行。

Basic Text Search 虚拟处理器
要运行 Basic Text Search 查询,需要使用 Basic Text Search 虚拟处理器。
必须先创建 Basic Text Search (BTS) 虚拟处理器,然后才能创建 Basic Text Search 索引
并对其运行查询。
创建 Basic Text Search 索引时,会自动添加 Basic Text Search 虚拟处理器。
Basic Text Search 虚拟处理器运行时不会让步;它一次处理一个索引操作。要同时运行多
个 Basic Text Search 索引操作和查询,请创建额外的 Basic Text Search 虚拟处理器。
将 VPCLASS 配置参数与 BTS 关键字一起使用以配置 Basic Text Search 虚拟处理器。
例如,要添加五个 BTS 虚拟处理器,请将以下行添加到 onconfig,然后重新启动数据库
服务器:
VPCLASS bts,num=5
使用 onmode -p 命令可动态添加 BTS 虚拟处理器,例如:
onmode -p 5 bts

MQ 消息传递虚拟处理器
要使用 MQ 消息传递,需要 MQ 虚拟处理器。
必须先创建 MQ 虚拟处理器,然后才能使用 MQ 消息传递。
执行 MQ 消息传递事务时,将自动创建 MQ 虚拟处理器。
MQ 虚拟处理器运行时不带生成器功能,所以一次处理一个操作。要同时执行多个 MQ
消息传递事务,请创建多个 MQ 虚拟处理器。
在 VPCLASS 配置参数中使用 MQ 关键字可配置 MQ 虚拟处理器。例如,要添加五个
MQ 虚拟处理器,请将以下行添加到 onconfig,然后重新启动数据库服务器:
VPCLASS mq,noyield,num=5
有关 VPCLASS 配置参数的更多信息,请参阅《GBase 8s 管理员参考》。有关 MQ 消
息传递的更多信息,请参阅《GBase 8s Database Extensions 用户指南》。

Web 要素服务虚拟处理器
要为地理空间数据使用 Web 要素服务,需要 Web 要素服务虚拟处理器。
必须先创建 WFS 虚拟处理器,然后才能使用 WFS。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 102 -
运行 WFS 例程时,将自动创建 WFS 虚拟处理器。
WFS 虚拟处理器运行时不带生成器功能,所以一次处理一个操作。要同时运行多个 WFS
例程,请创建多个 WFS 虚拟处理器。
在 VPCLASS 配置参数中使用 WFSVP 关键字可配置 WFS 虚拟处理器。例如,要添加
五个 WFS 虚拟处理器,请将以下行添加到 onconfig,然后重新启动数据库服务器:
VPCLASS wfsvp,noyield,num=5
有关 VPCLASS 配置参数的更多信息,请参阅《GBase 8s 管理员参考》。有关 WFS 的
更多信息,请参阅《GBase 8s Database Extensions 用户指南》。

XML 虚拟处理器
要执行 XML 发布,需要 XML 虚拟处理器。
必须先创建 XML 虚拟处理器,然后才能执行 XML 发布。
运行 XML 函数时,将自动创建 XML 虚拟处理器。
XML 虚拟处理器一次只能运行一个 XML 函数。要同时运行多个 XML 函数,请创建多
个 XML 虚拟处理器。
在 VPCLASS 配置参数中使用 IDSXMLVP 关键字可配置 XML 虚拟处理器。例如,要
添加五个 XML 虚拟处理器,请将以下行添加到 onconfig,然后重新启动数据库服务器:
VPCLASS idsxmlvp,num=5
使用 onmode -p 命令可动态添加 XML 虚拟处理器,例如:
onmode -p 5 idsxmlvp
有关 VPCLASS 配置参数和 onmode 实用程序的更多信息,请参阅《GBase 8s 管理员参
考》。有关 XML 发布的更多信息,请参阅《GBase 8s Database Extensions 用户指南》。

功能
元数据管理状态监测有两个状态信息可以查询:
express_cached_tables
表示当前内存中有多少个表实例。
express_cached_metadata
表示当前内存中所有表实例的元数据大小。
gbase> show variables like '%express_table%';
+-------------------------------------+------------+
| Variable_name
| Value
|
+-------------------------------------+------------+
| _gbase_express_table_clear_rate
| 10
|
| _gbase_express_table_limit
| 16384
|
| _gbase_express_table_metadata_limit | 1073741824 |
+-------------------------------------+------------+
3 rows in set (Elapsed: 00:00:00.01)
gbase> show status like '%express_cache%';
+-------------------------+-------+
| Variable_name
| Value |
+-------------------------+-------+
| express_cached_metadata | 5140
|
| express_cached_tables
| 1
|
+-------------------------+-------+
2 rows in set (Elapsed: 00:00:00.00)

您可定义变量为作用域中的本地的或全局的。
本部分描述本地变量。
在 SPL 例程中,
本地
变量:

仅对于该 SPL 例程的持续时间是有效的

每一次执行例程时,重置为它们的初始值或为用户传给该例程的值

不可有缺省值
您可在任一下列数据类型上定义本地变量:

内建的数据类型(除了 SERIAL、SERIAL8、BIGSERIAL、TEXT 或 BYTE 之外)


在执行该 SPL 例程之前,在数据库中定义的任何扩展的数据类型(row 类型、
opaque、distinct 或集合类型)
本地变量的作用域时在其中声明它的那个语句块。您可以不同的定义在该语句块之外使用
相同的变量名称。
要获取关于定义全局变量的更多信息,请参阅 声明全局变量。

本地变量的作用域
在定义本地变量的那个语句块内以及任何嵌套的语句块内,它是有效的,除非您在该语句
块中重新定义该变量。
在系统中的 SPL 过程的开头,定义并初始化整数变量 x、y 和 z。
图: 定义和初始化变量。
CREATE PROCEDURE scope()
DEFINE x,y,z INT;

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

LET x = 5;
LET y = 10;
LET z = x + y; --z is 15
BEGIN
DEFINE x, q INT;
DEFINE z CHAR(5);
LET x = 100;
LET q = x + y; -- q = 110
LET z = 'silly'; -- z receives a character value
END
LET y = x; -- y is now 5
LET x = z; -- z is now 15, not 'silly'
END PROCEDURE;
BEGIN 与 END 语句标记在其中定义整数变量 x 和 q 以及 CHAR 变量 z 的嵌套的语句
块。在嵌套的块内,重新定义的变量 x 掩盖原始的变量 x。在标记该嵌套的块结束的 END
语句之后,可再次访问 x 的原始值。

声明内建的数据类型的变量
声明为内建的 SQL 数据类型的变量可持有从那个内建的类型的列检索的值。您可将 SPL
变量声明为大部分内建的类型,
除了 BIGSERIAL、
SERIAL 和 SERIAL8 之外,
如下图所
示。
图: 内建的类型变量。
DEFINE x INT;
DEFINE y INT8;
DEFINE name CHAR(15);
DEFINE this_day DATETIME YEAR TO DAY;
您可声明适当的整数数据类型(诸如 BIGINT、INT 或 INT8)的 SPL 变量,来存储序列
列或序列对象的值。

声明智能大对象的变量
BLOB 或 CLOB 对象(或包含智能大对象的数据类型)的变量不包含该对象本身,而是
指向该对象的指针。下图展示如何为 BLOB 和 CLOB 对象定义变量。
图: BLOB 或 CLOB 对象的变量。
DEFINE a_blob BLOB;
DEFINE b_clob CLOB;

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


声明简单大对象的变量
简单大对象(TEXT 或 BYTE 对象)的变量不包含该对象本身,而是执行该对象的指针。
当您对 TEXT 或 BYTE 数据类型定义变量时,您必须在数据类型之前使用关键字
REFERENCES,如下图所示。
图: 在数据类型之前使用 REFERENCES 关键字。
DEFINE t REFERENCES TEXT;
DEFINE b REFERENCES BYTE;

声明集合变量
为了保持从数据库访存的集合,变量必须为类型 SET、MULTISET 或 LIST。
重要: 必须将集合变量定义为本地变量。您不可将集合变量定义为全局变量。
SET、MULTISET 或 LIST 类型的变量是保存在 DEFINE 语句中命名的类型的集合的集合变
量。下图展示如何定义 typed 集合变量。
图: 定义 typed 集合变量。
DEFINE a SET ( INT NOT NULL );

DEFINE b MULTISET ( ROW ( b1 INT,
b2 CHAR(50),
) NOT NULL );

DEFINE c LIST ( SET (DECIMAL NOT NULL) NOT NULL);
您必须始终将集合变量的元素定义为 NOT NULL。在此示例中,定义变量 a 来保存非
NULL 整数的 SET;变量 b 保存非 NULL row 类型的 MULTISET;变量 c 保存非 NULL
十进制值的非 NULL 集合的 LIST。
在变量定义中,您可在任何组合或深度中嵌套复合的类型,来与存储在您的数据库中的数
据类型相匹配。
您不可将一种类型的集合变量分配给另一类型的集合变量。例如,如果您将集合变量定义
为 SET,则您不可将另一 MULTISET 或 LIST 类型的集合变量分配给它。

声明 row 类型变量
Row 类型变量保存命名的和未命名的 row 类型的数据。
您可定义命名的 row 变量或未命
名的 row 变量。假设您定义如下图所示的命名的 row 类型。

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

图: 命名的和未命名的 row 变量。
CREATE ROW TYPE zip_t
(
z_code CHAR(5),
z_suffix CHAR(4)
);

CREATE ROW TYPE address_t
(
street VARCHAR(20),
city VARCHAR(20),
state CHAR(2),
zip zip_t
);

CREATE ROW TYPE employee_t
(
name VARCHAR(30),
address address_t
salary INTEGER
);

CREATE TABLE employee OF TYPE employee_t;
如果您以命名的 row 类型的名称定义变量,则该变量仅可保存那种 row 类型的数据。在
下图中,person 变量仅可保存 employee_t 类型的数据。
图: 定义 person 变量。
DEFINE person employee_t;
要定义保存在未命名的 row 类型中的数据的变量,请跟在 row 类型的字段之后使用
ROW 关键字,如下图所示。
图: 使用后跟 row 类型的字段的 ROW 关键字。
DEFINE manager ROW (name VARCHAR(30),
department VARCHAR(30),
salary INTEGER );
由于仅对未命名的 row 类型的结构等价进行类型检查,因此,以未命名的 row 类型定义
的变量可保存任何未命名的 row 类型的数据,
其有相同的字段数和相同的类型定义。
因此,
变量 manager 可保存下图中任何 row 类型的数据。

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

图: 未命名的 row 类型。
ROW ( name VARCHAR(30),
department VARCHAR(30),
salary INTEGER );

ROW ( french VARCHAR(30),
spanish VARCHAR(30),
number INTEGER );

ROW ( title VARCHAR(30),
musician VARCHAR(30),
price INTEGER );
重要:
在您使用 row 类型变量之前,
您必须使用 LET 语句或 SELECTINTO 语句来初始化该
row 变量。

声明 opaque 类型和 distinct 类型变量
Opaque 类型变量保存从 opaque 数据类型检索的数据。Distinct 类型变量保存从 distinct
数据类型检索的数据。如果您以 opaque 数据类型或 distinct 数据类型定义变量,则该变
量仅可保存那种类型的数据。
如果您定义名为 point 的 opaque 数据类型,和名为 centerpoint 的 distinct 数据类型,则您
可定义 SPL 变量来保存这两类数据,如下图所示。
图: 定义 SPL 变量来保存 opaque 和 distinct 数据类型。
DEFINE a point;
DEFINE b centerpoint;
变量 a 仅可保存类型 point 的数据,b 仅可保存类型 centerpoint 的数据。

使用 LIKE 子句来声明列数据的变量
如果您使用 LIKE 子句,
则数据库服务器定义有相同数据类型的变量作为表或视图中的列。

如果该列包含集合、row 类型或嵌套的复合类型,则该变量具有在该列中定义的复合的或
嵌套的复合类型。
在下图中,变量 loc1 定义 image 表中 locations 列的数据类型。
图: 为 image 表中的 locations 列定义 loc1 数据类型。
DEFINE loc1 LIKE image.locations;


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

声明 PROCEDURE 类型变量
在 SPL 例程中,您可定义类型 PROCEDURE 的变量,并将现有的 SPL 例程或外部例程
的名称分配给该变量。定义 PROCEDURE 类型的变量指示该变量是对用户定义的例程的
调用,而不是对同一名称的内建例程的调用。
例如,下图中的语句定义 length 为一个 SPL 过程或 SPL 函数,不作为内建的 LENGTH
函数。
图: 定义 length 作为 SPL 过程。
DEFINE length PROCEDURE;
LET x = length( a,b,c );
此定义在该语句块的作用域内禁用内建的 LENGTH 函数。
如果您已以名称 LENGTH 创建
了 SPL 或外部例程,则您可使用这样的定义。
由于 GBase 8s 支持例程重载,因此,您可以相同的名称定义多个 SPL 例程或外部例程。
如果您从 SPL 例程调用任何例程,则 GBase 8s 基于指定的参数和例程确定规则,确定使
用哪个例程。要获取关于例程重载和例程确定的信息,请参阅《GBase 8s 用户定义的例程
和数据类型开发者指南》。
提示:
如果您以相同的名称创建 SPL 例程作为聚集函数
(SUM、
MAX、
MIN、
AVG、
COUNT)
或使用名称 extend,则您必须以所有者名称来限定该例程。

带有变量的下标
您可随同 CHAR、VARCHAR、NCHAR、NVARCHAR、BYTE 或 TEXT 数据类型的变
量使用下标。下标指示您想要在变量内使用的起始的和终止的字符位置。
下标必须始终为常量。您不可使用变量作为下标。下图展示如何随同 CHAR(15) 变量使用
下标。
图: 带有 CHAR(15) 变量的下标。
DEFINE name CHAR(15);
LET name[4,7] = 'Ream';
SELECT fname[1,3] INTO name[1,3] FROM customer
WHERE lname = 'Ream';
在此示例中,将客户的姓置于 name 的位置 4 与 7 之间。将客户的名的前三个字符检索
到 name 的位置 1 至 3 内。由两个下标定界的变量的该部分称为子字符串。

变量与关键字歧义
如果您声明的变量的名字是 SQL 关键字,则可发生歧义。下列标识符的规则帮助您避免
SPL 变量、SPL 例程名称和内建的函数名称的歧义:

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


定义了的变量优先级最高。

以 DEFINE 语句中的 PROCEDURE 关键字定义的例程优先于 SQL 函数。

SQL 函数优先于那些存在但未以 DEFINE 语句中的 PROCEDURE 关键字标识
的 SPL 例程。
通常,请避免为变量的名称使用 ANSI 保留字。例如,您不可以名称 count 或 max 定义变
量,因为它们是聚集函数的名称。要了解您应避免用作变量名称的保留的关键字列表,请
参阅《GBase 8s SQL 指南:语法》中的“标识符”段。
要获取关于 SPL 例程名称与 SQL 函数名称之间的歧义的信息,
请参阅
《GBase 8s SQL 指
南:语法》。
变量和列名称
如果您为 SPL 变量使用一个您为列名称使用的同样的标识符,
则数据库服务器假定该标识
符的每一实例都是变量。请以表名称限定列名称,使用点符号表示法,以便将标识符用作
列名称。
在下图中的 SELECT 语句中,customer.lname 是列名称,lname 是变量名称。
图: SELECT 语句中的列名称和变量名称。
CREATE PROCEDURE table_test()

DEFINE lname CHAR(15);
LET lname = 'Miller';

SELECT customer.lname INTO lname FROM customer
WHERE customer_num = 502;
. . .
END PROCEDURE;
变量和 SQL 函数
如果您为 SPL 变量使用与为 SQL 函数一样的标识符,
则数据库服务器假定该表达式的每
一实例都是变量,并不允许使用该 SQL 函数。在定义该变量的代码块内,您不可使用该
SQL 函数。下图中的示例展示在其中定义名为 user 的变量的 SPL 过程内的块。此定义不
允许在 BEGIN END 块中使用 USER 函数。
图: 不允许在 BEGIN END 块中使用 USER 函数的过程。
CREATE PROCEDURE user_test()
DEFINE name CHAR(10);
DEFINE name2 CHAR(10);
LET name = user; -- the SQL function


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

BEGIN
DEFINE user CHAR(15); -- disables user function
LET user = 'Miller';
LET name = user; -- assigns 'Miller' to variable name
END
. . .
LET name2 = user; -- SQL function again