使用 SYSDBOPEN 和 SYSDBCLOSE 过程

要为一个或多个会话设置初始环境,创建并安装 sysdbopen() SPL 过程。该过程的典型影响是初始化会话的属性,而不需要在会话中显式定义属性。

如果用户通过不能修改应用程序代码或设置环境选项或环境变量的客户端应用程序访问数据库,则为一个或多个会话设置初始环境非常有用。

只要用户成功发出 DATABASE 或 CONNECT 语句以显式连接到安装了过程的数据库,就会执行 sysdbopen 过程。(但是当连接到本地数据库的用户调用远程 UDR 或执行通过使用 database:object or database@server:object 符号引用远程数据库对象的分布式 DML 操作是,不会在远程数据库中调用 sysdbopen 过程。)

这些过程时一般规则的例外情况,当在与 ANSI 不兼容的数据库中调用例程时, GBase 8s 会忽略 UDR 所有者的名称。对于除 sysdbopen 和 sysdbclose 之外的 UDR ,具有相同的 SQL 标识符但不同所有者名称的 UDR 的多个版本不能在同一数据库中注册,除非创建数据库的 CREATE DATABASE 语句也包括 WITH LOG MODE ANSI 关键字。

还可以创建 sysdbclose SPL 过程,当用户发出 LOSE DATABASE 或 DISCONNECT 语句从数据库断开连接时执行此过程,如果 PUBLIC.sysdbclose 过程已在数据库中注册,并且没有为当前用户注册 user.sysdbclose 过程,则当该用户与数据库断开连接时,将自动执行 PUBLIC.sysdbclose 过程。

您可以打开或关闭数据库时包含适当的有效 SQL 或 SPL 语言语句。对 SPL 过程中有效的 SQL 语句的一般限制也适用于这些例程。有关 SPL 例程中的 SQL 和 SPL 语句的限制,请参阅以下各节:
Important: sysdbopen 和 sysdbclose 过程是存储过程的作用域规则的例外。在一般 UDR 过程中,变量和语句的范围是局部的。当这些 SPL 过程退出时,SET PDQPRIORITY 和 SET ENVIRONMENT 语句设置不会保留。但是,在 sysdbopen 和 sysdbclose 过程中,设置会话环境的语句将保持有效,直到另一个语句重置选项,或会话结束。
例如,以下过程将事务隔离级别设置为 Repeatable Read,并设置 OPTCOMPIND 环境变量以指示查询优化器优先选择嵌套循环连接。当没有 user.sysdbopen 过程的用户连接到数据库时,将执行此例程:
CREATE PROCEDURE public.sysdbopen()
        SET ISOLATION TO REPEATABLE READ;
        SET ENVIRONMENT OPTCOMPIND '1';
        END PROCEDURE;

过程不接受参数和返回值。sysdbopen 和 sysdbclose 过程必须在您希望执行的数据库中注册。DBA 可以创建以下四个类别的 sysdbopen 和 sysdbclose 过程。

过程名
描述
user.sysdbopen
当指定的 user 将数据库作为当前数据库打开时执行此过程。
public.sysdbopen
如果没有应用 user.sysdbopen 过程,那么当将数据库作为当前数据库打开时执行此过程。要避免重复的 SPL 代码,您可以供用户指定的过程调用此过程。
user.sysdbclose
当指定的 user 关闭数据库时执行此过程,从数据库断开连接,或者解释用户会话。但是,如果当会话打开数据库时 user.sysdbclose 不存在,那么当会话关闭数据库时不会执行此过程。
public.sysdbclose
如果没有应用 user.sysdbclose 过程,则当用户关闭数据库服务器或从数据库服务器断开连接或结束会话时执行此过程。但是,如果当会话打开数据库时,public.sysdbopen 不存在,则当会话关闭数据库时不会执行此过程。

如果 CLOSE DATABASE 或 DISCONNECT 语句显式地终止连接,则数据库服务器调用 user.sysdbclose 过程(如果它在数据库中存在)或 public.sysdbclose (如果它存在并且不被用户使用)。如果应用程序在不发出 CLOSE DATABASE 或 DISCONNECT 语句的情况下终止,则数据库服务器强制执行数据库的隐式关闭,并执行 sysdbclose 过程(如果有该名称的 UDR 由用户或 PUBLIC 拥有)。

请确保正确设置文件访问权限,以允许预期用户执行 SPL 过程语句。例如,如果 SPL 过程执行将输出写入本地目录的命令。则必须设置权限以允许用户写入此目录。如果希望在许可失败时继续该过程,请为此条件包含 ON EXCEPTION 错误处理程序。

有关可以出现在 SPL 例程中的 SQL 语句以及有关事务和角色的 SPL 支持的更多信息,请参阅语句块一节。

Warning: 如果 sysdbclose 过程失败,该失败会被忽视。然而,如果 sysdbopen 过程失败,数据库不会被打开。
为了避免无法打开数据库的情况,请在编写和调试 sysdbopen 过程时采取以下预防措施: 来自这些过程的故障可以有系统生成或由 SPL 的 RAISE EXCEPTION 语句在过程中进行模拟。如果在连接时为用户调用的 sysdbopen 例程包含此语句,则该用户无法连接到数据库。有关更多信息,请参阅 RAISE EXCEPTION 的描述。

出于安全原因,非 DBA 无法阻止这些过程的执行。然而,对于一些应用程序,例如 ad hoc 查询应用程序,用户可以执行随后该表环境的命令和 SQL 语句。

sysdbopen 过程中定义的缺省角色优先于用户建立与数据库的连接时用户持有的任何其它角色,其中 sysdbopen 成功地为该用户指定了缺省角色。

由 user.sysdbopen 或 user.sysdbclose 过程中的 DDL 语句创建的任何数据库对象都由连接的用户所有,并且在 PUBLIC.sysdbopen 或 PUBLIC.sysdbclose 内创建的任何对象都由 PUBLIC 用户标识拥有,除非对象名称在 DDL 语句中声明时,被某个其它所有者名称完全限定。

对于兼容 ANSI 的数据库,在 CREATE PROCEDURE 语句的 sysdbopen 或 sysdbclose 定义的末尾需要显式的 COMMIT WORK 语句,以防止 sysdbopen 或 sysdbclose 过程执行的 SQL 语句的任何隐式事务在终止过程时回滚。(省略 COMMIT WORK 语句不会导致连接失败,但会在打开和回滚事务时浪费资源。)

有关这些过程中无效的 SQL 语句的列表,请参阅 SQL 语句在 SPL 语句块中有效。有关在这些过程中有效的 SPL 语句,请参阅 SPL 语句的子集在语句块中有效。

有关如何编写和安装 SPL 过程的一般信息,请参阅 GBase 8s SQL 教程指南中 SPL 例程一节。