数据库运维11 min read

瀚高数据库V9.0 Oracle兼容性深度解析:从迁移到适配

瀚高数据库V9.0 Oracle兼容性深度解析:从迁移到适配

前言

在国产化替代浪潮中,从 Oracle 迁移到国产数据库的最大障碍就是兼容性。瀚高数据库 V9.0 提供了业界领先的 Oracle 兼容能力,覆盖了数据类型、内置函数、PL/SQL、存储过程、包、同义词、DBLink、闪回等数十项核心特性。

本文基于官方 Oracle 兼容性手册,系统梳理 HGDB V9.0 的 Oracle 兼容体系,帮助运维和开发人员平稳完成数据库迁移。

一、兼容性全景图

HGDB V9.0 的 Oracle 兼容性覆盖以下层次:

┌─────────────────────────────────────────────────────┐
│                    应用层                            │
│  存储过程 / 函数 / 包 / 同义词 / DBLink / 触发器      │
├─────────────────────────────────────────────────────┤
│                    SQL 层                            │
│  MERGE / CONNECT BY / ROWNUM / (+)连接 / 序列        │
├─────────────────────────────────────────────────────┤
│                   函数层                             │
│  100+ Oracle 内置函数 / 分析函数 / 转换函数           │
├─────────────────────────────────────────────────────┤
│                   类型层                             │
│  NUMBER / VARCHAR2 / DATE / TIMESTAMP / CLOB / BLOB │
├─────────────────────────────────────────────────────┤
│                   系统层                             │
│  系统视图 / 数据字典 / 系统包 (DBMS_*)                │
└─────────────────────────────────────────────────────┘

二、数据类型兼容

2.1 完整的数据类型映射

HGDB V9.0 直接支持以下 Oracle 原生数据类型,无需修改表结构:

-- Oracle 原生类型在 HGDB 中直接可用
CREATE TABLE employee (
    emp_id      NUMBER(10),           -- 数值类型
    emp_name    VARCHAR2(100),         -- 变长字符串
    hire_date   DATE,                  -- 日期(含时间)
    salary      NUMBER(10,2),
    bonus       BINARY_FLOAT,          -- 单精度浮点
    commission  BINARY_DOUBLE,         -- 双精度浮点
    created_at  TIMESTAMP,             -- 时间戳
    tz_time     TIMESTAMP WITH TIME ZONE,
    local_tz    TIMESTAMP WITH LOCAL TIME ZONE,
    work_period INTERVAL YEAR TO MONTH,  -- 年月间隔
    task_time   INTERVAL DAY TO SECOND,  -- 日时间隔
    resume      CLOB,                  -- 大文本
    photo       BLOB                   -- 二进制
);

关键类型说明:

Oracle 类型 HGDB 支持 说明
NUMBER(p,s) 原生支持 与 Oracle 精度一致
VARCHAR2(n) 原生支持 字符串比较规则与 Oracle 一致
DATE 原生支持 含时分秒
TIMESTAMP 原生支持 纳秒精度
TIMESTAMP WITH TIME ZONE 原生支持 含时区信息
INTERVAL YEAR TO MONTH 原生支持 年月间隔计算
INTERVAL DAY TO SECOND 原生支持 日时间隔计算
BINARY_FLOAT/DOUBLE 原生支持 IEEE 754 浮点
CLOB/BLOB 原生支持 大对象存储

2.2 日期函数完整兼容

-- 以下 Oracle 日期函数在 HGDB 中全部可用
SELECT
    SYSDATE,                                    -- 当前日期时间
    SYSTIMESTAMP,                               -- 当前时间戳
    ADD_MONTHS(hire_date, 6) AS after_6_months,
    LAST_DAY(hire_date) AS month_end,
    NEXT_DAY(hire_date, 'MONDAY') AS next_monday,
    MONTHS_BETWEEN(SYSDATE, hire_date) AS work_months,
    ROUND(hire_date, 'MONTH') AS rounded,
    TRUNC(hire_date, 'YEAR') AS year_start,
    TO_DATE('2026-07-01', 'YYYY-MM-DD'),
    TO_CHAR(hire_date, 'YYYY年MM月DD日') AS cn_date,
    TO_TIMESTAMP('2026-07-01 14:30:00', 'YYYY-MM-DD HH24:MI:SS'),
    EXTRACT(YEAR FROM hire_date) AS hire_year
FROM employee;

2.3 字符串与转换函数

-- 字符串处理
SELECT
    LENGTH('瀚高数据库'),         -- 字符长度
    LENGTHB('瀚高数据库'),        -- 字节长度
    SUBSTR(emp_name, 1, 3),
    INSTR(emp_name, '张'),
    LPAD(emp_id, 8, '0'),
    REPLACE(emp_name, ' ', ''),
    CONCAT(first_name, last_name)
FROM employee;

-- 类型转换
SELECT
    TO_NUMBER('12345.67'),
    TO_CHAR(salary, 'L999,999.00'),
    NVL(bonus, 0),               -- NULL 替换
    NVL2(bonus, '有奖金', '无奖金'),
    DECODE(status, 1, '在职', 2, '离职', '未知'),
    COALESCE(bonus, commission, 0)
FROM employee;

三、PL/SQL 兼容 — 存储过程与函数

HGDB V9.0 全面兼容 Oracle PL/SQL 语法:

-- Oracle 风格的存储过程
CREATE OR REPLACE PROCEDURE update_salary(
    p_emp_id    IN NUMBER,
    p_increase  IN NUMBER DEFAULT 0.1,
    p_new_sal   OUT NUMBER
) AS
    v_old_salary NUMBER;
BEGIN
    SELECT salary INTO v_old_salary
    FROM employee WHERE emp_id = p_emp_id;

    p_new_sal := v_old_salary * (1 + p_increase);

    UPDATE employee
    SET salary = p_new_sal
    WHERE emp_id = p_emp_id;

    COMMIT;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR(-20001, '员工不存在');
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
END;
/

-- 调用存储过程
DECLARE
    v_sal NUMBER;
BEGIN
    update_salary(1001, 0.15, v_sal);
    DBMS_OUTPUT.PUT_LINE('新工资: ' || v_sal);
END;
/

支持的特殊语法:

-- 嵌套函数(Oracle 特有)
CREATE OR REPLACE FUNCTION calc_bonus(p_salary NUMBER) RETURN NUMBER AS
    FUNCTION calc_tax(p_amount NUMBER) RETURN NUMBER AS
    BEGIN
        RETURN p_amount * 0.03;
    END;
BEGIN
    RETURN p_salary - calc_tax(p_salary);
END;
/

-- 自治事务
CREATE OR REPLACE PROCEDURE log_access(p_user VARCHAR2) AS
    PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    INSERT INTO access_log(user_name, access_time)
    VALUES (p_user, SYSDATE);
    COMMIT;
END;
/

四、包(PACKAGE)与系统包

4.1 自定义包

-- 创建包规范
CREATE OR REPLACE PACKAGE emp_pkg AS
    FUNCTION get_salary(p_emp_id NUMBER) RETURN NUMBER;
    PROCEDURE raise_salary(p_emp_id NUMBER, p_pct NUMBER);
END emp_pkg;
/

-- 创建包体
CREATE OR REPLACE PACKAGE BODY emp_pkg AS
    FUNCTION get_salary(p_emp_id NUMBER) RETURN NUMBER AS
        v_sal NUMBER;
    BEGIN
        SELECT salary INTO v_sal FROM employee WHERE emp_id = p_emp_id;
        RETURN v_sal;
    END;

    PROCEDURE raise_salary(p_emp_id NUMBER, p_pct NUMBER) AS
    BEGIN
        UPDATE employee SET salary = salary * (1 + p_pct)
        WHERE emp_id = p_emp_id;
        COMMIT;
    END;
END emp_pkg;
/

-- 调用包
SELECT emp_pkg.get_salary(1001) FROM dual;
EXEC emp_pkg.raise_salary(1001, 0.1);

4.2 系统包支持

HGDB V9.0 内置了以下 Oracle 兼容系统包:

系统包 功能
DBMS_OUTPUT 调试输出
DBMS_JOB 定时任务调度
DBMS_SQL 动态 SQL 执行
DBMS_LOB 大对象操作
UTL_FILE 文件读写
DBMS_RANDOM 随机数生成
-- DBMS_JOB 创建定时任务
DECLARE
    job_id NUMBER;
BEGIN
    DBMS_JOB.SUBMIT(
        job => job_id,
        what => 'update_salary_daily;',
        next_date => TRUNC(SYSDATE) + 1,
        interval => 'TRUNC(SYSDATE) + 1'
    );
    COMMIT;
END;
/

-- DBMS_OUTPUT 调试
BEGIN
    DBMS_OUTPUT.PUT_LINE('处理开始...');
    FOR rec IN (SELECT emp_id, emp_name FROM employee) LOOP
        DBMS_OUTPUT.PUT_LINE('处理员工: ' || rec.emp_name);
    END LOOP;
END;
/

五、同义词(SYNONYM)

HGDB V9.0 完整支持 Oracle 同义词机制:

-- 创建私有同义词
CREATE SYNONYM emp FOR hr.employee;

-- 创建公共同义词
CREATE PUBLIC SYNONYM pub_emp FOR hr.employee;

-- 使用同义词
SELECT * FROM emp;          -- 等同于 SELECT * FROM hr.employee;
INSERT INTO emp VALUES(...);

-- 删除同义词
DROP SYNONYM emp;
DROP PUBLIC SYNONYM pub_emp;

同义词在 DML 和 DDL 语句中均可使用,支持跨 Schema 引用。

六、MERGE 语句与序列

-- MERGE 语句(Oracle 风格)
MERGE INTO employee e
USING (SELECT emp_id, new_salary FROM salary_update) s
ON (e.emp_id = s.emp_id)
WHEN MATCHED THEN
    UPDATE SET e.salary = s.new_salary
WHEN NOT MATCHED THEN
    INSERT (emp_id, salary) VALUES (s.emp_id, s.new_salary);

-- 序列(Sequence)
CREATE SEQUENCE emp_seq
    START WITH 1000
    INCREMENT BY 1
    MAXVALUE 999999
    CACHE 20;

-- 自增列(IDENTITY)
CREATE TABLE orders (
    order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    order_no  VARCHAR2(50),
    created   DATE DEFAULT SYSDATE
);

七、DBLink — 跨数据库访问

-- 创建 DBLink 到远程 Oracle 数据库
CREATE EXTENSION oracle_fdw;

CREATE SERVER oracle_server
    FOREIGN DATA WRAPPER oracle_fdw
    OPTIONS (dbserver '//192.168.1.100:1521/ORCL');

CREATE USER MAPPING FOR highgo
    SERVER oracle_server
    OPTIONS (user 'scott', password 'tiger');

-- 创建外部表映射
CREATE FOREIGN TABLE remote_emp (
    emp_id  INTEGER,
    ename   VARCHAR(50),
    sal     NUMERIC(10,2)
) SERVER oracle_server
OPTIONS (schema 'SCOTT', table 'EMP');

-- 直接查询远程表
SELECT * FROM remote_emp WHERE sal > 3000;

八、分区表兼容

8.1 Interval 分区(Oracle 11g+ 特性)

-- 按月自动创建分区
CREATE TABLE sales (
    sale_id     NUMBER,
    sale_date   DATE,
    amount      NUMBER(12,2)
) PARTITION BY RANGE (sale_date) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
(
    PARTITION p202601 VALUES LESS THAN (TO_DATE('2026-02-01', 'YYYY-MM-DD'))
);

-- 插入数据会自动创建缺失的分区
INSERT INTO sales VALUES (1, DATE '2026-07-15', 50000);
-- 自动创建 p202607 分区!

8.2 分区表维护

-- 手动创建 Interval 分区
ALTER TABLE sales ADD PARTITION
    p_manual VALUES LESS THAN (TO_DATE('2026-08-01', 'YYYY-MM-DD'));

-- 修改分区间隔
ALTER TABLE sales SET INTERVAL (NUMTOYMINTERVAL(1, 'QUARTER'));

-- 删除分区
ALTER TABLE sales DROP PARTITION p202601;

-- 分离分区(转为普通表)
ALTER TABLE sales DETACH PARTITION p202601;

九、其他重要兼容特性

9.1 闪回(Flashback)

-- 闪回查询(查看历史数据)
SELECT * FROM employee AS OF TIMESTAMP
    TO_TIMESTAMP('2026-07-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS');

-- 闪回表到删除前(回收站功能)
FLASHBACK TABLE employee TO BEFORE DROP;

-- 清空回收站
PURGE RECYCLEBIN;

9.2 ROWNUM 和 CONNECT BY

-- ROWNUM 支持
SELECT * FROM employee WHERE ROWNUM <= 10;

-- 层次查询
SELECT emp_id, emp_name, manager_id, LEVEL
FROM employee
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id;

9.3 SUBTYPE 类型

-- 定义子类型(带约束)
DECLARE
    SUBTYPE pos_number IS NUMBER(10,2) NOT NULL;
    v_salary pos_number := 5000.00;
BEGIN
    DBMS_OUTPUT.PUT_LINE(v_salary);
END;
/

十、迁移工具与流程

HGDB V9.0 提供专用的迁移工具,支持从 Oracle 自动迁移:

# 迁移工具核心功能:
# 1. 自动扫描 Oracle Schema 对象
# 2. 类型映射(Oracle → HGDB)
# 3. 数据迁移(全量 + 增量)
# 4. 存储过程/函数/包自动转换
# 5. 迁移校验报告

迁移流程建议:

1. 评估阶段
   ├── 扫描 Oracle 对象清单
   ├── 识别不兼容的功能
   └── 制定迁移方案

2. 迁移阶段
   ├── 结构迁移(DDL)
   ├── 数据迁移(全量)
   ├── 对象迁移(存储过程等)
   └── 增量同步

3. 验证阶段
   ├── 数据一致性校验
   ├── 功能测试
   └── 性能基准测试

4. 切换阶段
   ├── 最终增量同步
   ├── 业务割接
   └── 监控观察

总结

瀚高数据库 V9.0 的 Oracle 兼容能力覆盖了生产环境中最常用的 90%+ 特性,从数据类型到 PL/SQL、从包到同义词、从 DBLink 到闪回,形成了一个完整的 Oracle 兼容生态。

迁移前的关键评估点:

评估项 兼容度 注意事项
数据类型 NUMBER/VARCHAR2/DATE 直接支持
内置函数 100+ 函数覆盖
PL/SQL 中高 存储过程、包、自治事务支持
系统包 DBMS_OUTPUT/DBMS_JOB 等核心包可用
分区表 Interval 分区完整支持
闪回 查询和表级闪回支持
DBLink 通过 FDW 实现

迁移原则:先评估、后迁移、逐模块验证,切忌一次性全量切换。对于不兼容的特性,提前制定好替代方案。

分享:

相关文章