模拟 Oracle 包变量

Oracle 支持将变量、类型、存储过程和函数封装到包中。 转换 Oracle 包时,需要转换:

  • 过程和函数 - 公共和私有
  • 变量
  • 游标
  • 初始化例程

本文介绍了 Oracle SQL Server 迁移助手 (SSMA) 如何将包变量转换为SQL Server。

转换基础知识

为了存储包变量,适用于 Oracle 的 SSMA 使用驻留在特殊 ssma_oracle 架构中的存储过程以及 ssma_oracle.db_storage 表。 此表按 SPID (会话标识符) 和登录时间进行筛选。 通过此筛选,可以区分不同会话的变量。

在每个转换的包过程 SSMA 的开头,将调用 ssma_oracle.db_check_init_package 特殊过程,该过程检查包是否已初始化,并在需要时初始化它。 每个初始化过程都会清理存储表,并为每个包变量设置默认值。

示例

请考虑以下示例来转换多个包变量:

CREATE OR REPLACE PACKAGE MY_PACKAGE
IS
    space varchar(1) := ' ';
    unitname varchar(128) := 'My Simple Package';
    ts date := sysdate;
END;

SSMA 将其转换为以下 Transact-SQL 代码:

CREATE PROCEDURE dbo.MY_PACKAGE$SSMA_Initialize_Package
AS
BEGIN
    EXECUTE ssma_oracle.db_clean_storage

    EXECUTE ssma_oracle.set_pv_varchar
        DB_NAME(),
        'DBO',
        'MY_PACKAGE',
        'SPACE',
        ' '

    EXECUTE ssma_oracle.set_pv_varchar
        DB_NAME(),
        'DBO',
        'MY_PACKAGE',
        'UNITNAME',
        'My Simple Package'

    DECLARE
        @temp datetime2

    SET @temp = sysdatetime()

    EXECUTE sysdb.ssma_oracle.set_pv_datetime2
      DB_NAME(),
      'DBO',
      'MY_PACKAGE',
      'TS',
      @temp
END

模拟包变量的 Get 和 Set 方法

Oracle 使用 Get 包变量和 Set 方法,以避免让其他子程序直接读取和写入它们。 如果要求在同一会话中的子程序调用之间保留某些变量可用,则这些变量将被视为全局变量。

为了克服此范围规则,适用于 Oracle 的 SSMA 对每种变量类型都使用存储过程 ssma_oracle.set_pv_varchar 。 为了访问这些变量,SSMA 使用一组独立于 get_* 事务的过程和 set_* 函数。

Oracle 中的数据类型 SSMA Set 过程
VARCHAR ssma_oracle.set_pv_varchar
DATE ssma_oracle.set_pv_datetime2
CHAR ssma_oracle.set_pv_varchar
INT ssma_oracle.set_pv_float
FLOAT ssma_oracle.set_pv_float

为了区分不同会话中的变量,SSMA 会存储变量及其 SPID (会话标识符) 和会话的登录时间。 因此, get_* 过程 set_* 使变量独立于运行它们的会话。