强制重新优化以避免索引和先前预编译语句的问题

如果启用了 AUTO_REPREPARE 配置参数和 IFX_AUTO_REPREPARE 会话环境变量,那么在 DDL 语句修改了引用表的模式之后,GBase 8s 会自动重新编译预编译语句和 SPL 例程。如果禁用 AUTO_REPREPARE 配置参数或 IFX_AUTO_REPREPARE 会话环境变量,可以执行步骤以防止错误。

如果禁用了 AUTO_REPREPARE 配置参数或 IFX_AUTO_REPREPARE 会话环境变量,那么在由 SPL 例程间接引用或预编译对象引用的表模式被修复之后执行该预编译对象或 SPL 例程时,将导致以下错误。
-710  Table <table-name> has been dropped, altered, or renamed.
此错误可以与显式预编译语句一起发生。这些语句具有以下形式:
PREPARE statement id FROM quoted string

在数据库服务器中预编译语句之后和执行该语句之前,该语句所引用的表可能已重命名或更改,也可能更改了表的结构。结果,可能发生一些问题。

在准备语句之后将索引添加到该表也可能导致该语句失效。如果游标引用无效的预编译语句,那么游标随后的 OPEN 命令将失败;即使 OPEN 命令具有 WITH REOPTIMIZATION 子句,也将发生故障。

如果在准备语句之后添加了索引,那么您必须重新准备该语句并重新声明游标。如果游标基于无效的预编译语句,那么您不能简单地重新打开游标。

此错误也可以与 SPL 例程一起发生。数据库服务器第一次执行新的 SPL 例程之前,它将优化 SPL 例程中的代码(语句)。优化使代码取决于过程引用的表的结构。如果表结构在过程优化之后和执行之前进行了更改,那么可能发生此错误。

每个 SPL 例程在第一次运行时(不是在创建时)进行优化。此行为说明了 SPL 例程可能在第一次运行时成功,但是随后在几乎相同的环境下可能失败。SPL 例程的失败也可能是间歇性的,这是因为在一个执行期间失败将强制内部警告在下一个执行之前重新优化过程。

数据库服务器保留 SPL 例程显式引用的表的列表。只要修改了任何一个显式引用的表,数据库服务器将在下一次执行过程时重新优化过程。

但是,如果 SPL 例程取决于仅以间接方式引用的表,那么数据库服务器将无法检测到在更改该表之后重新优化过程的需要。例如,如果 SPL 例程调用触发器,那么可以按间接方式引用表。如果触发器引用的表(但不是由 SPL 例程直接引用)发生了更改,那么数据库服务器在运行之前不会知道它是否应该重新优化 SPL 例程。更改了表之后运行过程时,将可能发生此错误。

使用两种方法中的一种可以从该错误中进行恢复:
要防止发生此错误,您可以强制重新优化 SPL 例程。要强制重新优化,请执行以下语句:
UPDATE STATISTICS FOR PROCEDURE procedure name
您可以使用以下两种方式中的一种将该语句添加到程序中: 为提高效率,您可以通过在程序中使用频率较少的操作(更改对象方式或执行过程)来放置 UPDATE STATISTICS 语句。大多数情况下,程序中使用频率较少的操作是更改对象方式。

遵循从该错误中进行恢复的方法时,您必须按间接方式为每个引用已更改的表的过程执行 UPDATE STATISTICS 语句,除非过程也显示引用了表。

仅通过重新运行 SPL 例程,您也可以从该错误中进行恢复。存储过程第一次失败时,数据库服务器将该过程标记为需要重新优化。下一次运行该过程时,数据库服务器在运行它之前对其进行重新优化。但是,两次运行 SPL 例程可能不切实际或不安全。较安全的方法是使用 UPDATE STATISTICS 语句来强制对该过程进行重新优化。