Vastbase G100 Oracle 兼容性深度解析
国产数据库替代 Oracle,最大的难点不是性能,而是兼容性。应用系统经过多年迭代,积累了大量 Oracle 特有语法、存储过程、触发器,改写成本极高。Vastbase G100 的核心卖点就是 Oracle 兼容——官方兼容性手册有 1799 页,覆盖了从数据类型到 PL/SQL 的方方面面。本文从中提炼关键内容,帮助评估迁移可行性。
兼容性架构
Vastbase G100 的 Oracle 兼容不是简单的语法翻译,而是从内核层面实现的深度兼容。初始化数据库时指定 DBCOMPATIBILITY='A' 即启用 Oracle 兼容模式,此后数据库的行为在多个层面模拟 Oracle:
- 数据类型层:支持 Oracle 全部内置数据类型,包括 NUMBER、VARCHAR2、DATE、BLOB/CLOB、BFILE 等
- 函数层:兼容 200+ Oracle 内置函数
- PL/SQL 层:支持存储过程、函数、包、触发器,语法高度兼容
- SQL 语法层:支持 DUAL 表、ROWNUM、CONNECT BY 层次查询、MERGE INTO 等
- 对象管理层:支持序列、同义词、物化视图、目录对象等
数据类型兼容
数值类型
| Oracle 类型 | Vastbase 支持 | 说明 |
|---|---|---|
| NUMBER | ✅ | 精度和标量完全兼容 |
| NUMBER(p,s) | ✅ | 支持指定精度和标量 |
| BINARY_FLOAT | ✅ | 4 字节单精度浮点 |
| BINARY_DOUBLE | ✅ | 8 字节双精度浮点 |
| PLS_INTEGER | ✅ | 整数类型 |
| FLOAT | ✅ | 浮点类型 |
-- NUMBER 类型测试
CREATE TABLE num_test (
id NUMBER,
price NUMBER(10,2),
ratio NUMBER(5,4)
);
INSERT INTO num_test VALUES (1, 99999999.99, 0.9999);
SELECT * FROM num_test;
字符类型
| Oracle 类型 | Vastbase 支持 | 最大长度 | 说明 |
|---|---|---|---|
| VARCHAR2 | ✅ | 32767 字节 | 可变长字符 |
| CHAR | ✅ | 2000 字节 | 定长字符 |
| NCHAR | ✅ | 2000 字符 | 国家字符集定长 |
| NVARCHAR2 | ✅ | 32767 字符 | 国家字符集可变长 |
| LONG | ✅ | 2GB | 可变长字符串(不推荐) |
| CLOB | ✅ | 1GB-1 | 字符大对象 |
| NCLOB | ✅ | 1GB-1 | 国家字符集大对象 |
LONG 类型注意:一个表只能有一个 LONG 列,不能出现在 WHERE、GROUP BY、ORDER BY 中,不能创建索引。Vastbase 完全继承了这些限制,建议迁移时改用 CLOB。
日期时间类型
| Oracle 类型 | Vastbase 支持 | 说明 |
|---|---|---|
| DATE | ✅ | 存储日期和时间(精度到秒) |
| TIMESTAMP | ✅ | 带小数秒的时间戳 |
| TIMESTAMP WITH TIME ZONE | ✅ | 带时区 |
| INTERVAL YEAR TO MONTH | ✅ | 年月间隔 |
| INTERVAL DAY TO SECOND | ✅ | 天秒间隔 |
DATE 类型是迁移中最常用的类型。Vastbase 的 DATE 类型行为与 Oracle 完全一致:
-- DATE 类型行为测试
SELECT sysdate FROM dual;
-- 返回: 2026-07-03 10:30:00
-- 日期相减返回天数(NUMBER 类型)
SELECT to_date('2026-07-10','yyyy-mm-dd') - to_date('2026-07-01','yyyy-mm-dd') FROM dual;
-- 返回: 9
-- 日期相减再做乘法返回数值
SELECT (sysdate - to_date('2026-01-01','yyyy-mm-dd')) * 86400 FROM dual;
-- 返回从年初到现在的秒数
大对象类型
BLOB 和 CLOB 是 Oracle 应用中最常见的大对象类型,Vastbase 通过 TOAST 表存储未经压缩的原始数据:
-- CLOB 基本操作
CREATE TABLE doc_test (
id NUMBER PRIMARY KEY,
content CLOB,
created DATE DEFAULT sysdate
);
INSERT INTO doc_test VALUES (1, TO_CLOB('测试文本'), sysdate);
SELECT id, content, TO_CHAR(created, 'yyyy-mm-dd') FROM doc_test;
-- BLOB 通过 DBMS_LOB 管理
DECLARE
v_blob BLOB;
BEGIN
SELECT content INTO v_blob FROM blob_test WHERE id = 1;
DBMS_LOB.OPEN(v_blob, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.WRITEAPPEND(v_blob, 10, UTL_RAW.CAST_TO_RAW('append_data'));
DBMS_LOB.CLOSE(v_blob);
END;
/
大对象限制:不支持基于 BLOB/CLOB 创建索引;不支持直接比较操作;列存表不支持 BLOB/CLOB 类型;不支持修改表中 LOB 列类型。
BFILE 类型
BFILE 是 Oracle 特有的只读外部文件引用类型,Vastbase 完整支持:
-- 1. 创建 directory 对象
CREATE DIRECTORY d_bfile AS '/home/vastbase';
-- 2. 创建包含 BFILE 列的表
CREATE TABLE test_bfile (
id NUMBER,
file_ref BFILE
);
-- 3. 插入数据
INSERT INTO test_bfile VALUES (1, BFILENAME('d_bfile', 'data.txt'));
-- 4. 查询
SELECT * FROM test_bfile;
函数兼容
Vastbase 兼容 200+ Oracle 内置函数,以下是最常用的分类总结:
数值函数
| 函数 | 说明 | 示例 |
|---|---|---|
| MOD(n2, n1) | 取模,n1=0 时返回 n2 | MOD(10, 3) → 1 |
| ROUND(n, d) | 四舍五入 | ROUND(3.14159, 2) → 3.14 |
| TRUNC(n, d) | 截断 | TRUNC(3.14159, 2) → 3.14 |
| CEIL(n) | 向上取整 | CEIL(3.1) → 4 |
| FLOOR(n) | 向下取整 | FLOOR(3.9) → 3 |
| POWER(n2, n1) | 幂运算 | POWER(2, 10) → 1024 |
| BITAND(n1, n2) | 按位与 | BITAND(6, 3) → 2 |
字符函数
| 函数 | 说明 |
|---|---|
| INSTR(str, sub, pos, nth) | 查找子串位置 |
| LENGTHB(char) | 字节长度 |
| LPAD(str, len, pad) | 左填充 |
| LTRIM(c1, c2) | 左截断 |
| REPLACE(str, search, replace) | 替换 |
| SUBSTR(str, pos, len) | 截取子串 |
| TRANSLATE(str, from, to) | 字符映射 |
| REGEXP_REPLACE | 正则替换 |
| REGEXP_SUBSTR | 正则提取 |
日期函数
| 函数 | 说明 |
|---|---|
| SYSDATE | 当前日期时间 |
| ADD_MONTHS(date, n) | 月份加减 |
| LAST_DAY(date) | 月末日期 |
| MONTHS_BETWEEN(d1, d2) | 月份差 |
| NEXT_DAY(date, char) | 下一个指定星期 |
| EXTRACT(field FROM date) | 提取日期分量 |
| TRUNC(date, fmt) | 日期截断 |
分析函数
Vastbase 兼容 Oracle 分析函数(窗口函数)语法:
-- ROW_NUMBER 排名
SELECT ename, deptno, sal,
ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal DESC) rn
FROM emp;
-- LAG/LEAD 取偏移行
SELECT ename, sal,
LAG(sal, 1, 0) OVER (ORDER BY sal) prev_sal,
LEAD(sal, 1, 0) OVER (ORDER BY sal) next_sal
FROM emp;
-- RATIO_TO_REPORT 占比
SELECT ename, sal,
RATIO_TO_REPORT(sal) OVER () sal_ratio
FROM emp;
特殊函数
| 函数 | 说明 |
|---|---|
| DECODE(expr, s1, r1, ..., default) | 条件匹配返回 |
| NVL(expr, default) | NULL 替换 |
| NVL2(expr, val1, val2) | 非 NULL 返回 val1 |
| COALESCE(expr1, expr2, ...) | 返回第一个非 NULL |
| LNNVL(condition) | 条件取反(含 NULL 处理) |
| NANVL(n2, n1) | NAN 替换 |
| EMPTY_BLOB() / EMPTY_CLOB() | 返回空 LOB |
| DUMP(text) | 返回内部表示 |
PL/SQL 兼容
存储过程
CREATE OR REPLACE PROCEDURE transfer_account(
p_from_id NUMBER,
p_to_id NUMBER,
p_amount NUMBER
) AS
v_balance NUMBER;
BEGIN
SELECT balance INTO v_balance FROM accounts WHERE id = p_from_id;
IF v_balance < p_amount THEN
RAISE_APPLICATION_ERROR(-20001, '余额不足');
END IF;
UPDATE accounts SET balance = balance - p_amount WHERE id = p_from_id;
UPDATE accounts SET balance = balance + p_amount WHERE id = p_to_id;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
ROLLBACK;
RAISE_APPLICATION_ERROR(-20002, '账户不存在');
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
/
自定义函数
CREATE OR REPLACE FUNCTION calc_tax(
p_salary NUMBER,
p_rate NUMBER DEFAULT 0.1
) RETURN NUMBER AS
v_tax NUMBER;
BEGIN
v_tax := p_salary * p_rate;
RETURN v_tax;
END;
/
包(Package)
Vastbase 支持 Oracle 的包(Package)概念,将相关过程和函数组织在一起:
-- 创建包头
CREATE OR REPLACE PACKAGE account_pkg AS
PROCEDURE deposit(p_id NUMBER, p_amount NUMBER);
PROCEDURE withdraw(p_id NUMBER, p_amount NUMBER);
FUNCTION get_balance(p_id NUMBER) RETURN NUMBER;
END account_pkg;
/
-- 创建包体
CREATE OR REPLACE PACKAGE BODY account_pkg AS
PROCEDURE deposit(p_id NUMBER, p_amount NUMBER) IS
BEGIN
UPDATE accounts SET balance = balance + p_amount WHERE id = p_id;
COMMIT;
END;
PROCEDURE withdraw(p_id NUMBER, p_amount NUMBER) IS
BEGIN
UPDATE accounts SET balance = balance - p_amount WHERE id = p_id;
COMMIT;
END;
FUNCTION get_balance(p_id NUMBER) RETURN NUMBER IS
v_bal NUMBER;
BEGIN
SELECT balance INTO v_bal FROM accounts WHERE id = p_id;
RETURN v_bal;
END;
END account_pkg;
/
触发器
CREATE OR REPLACE TRIGGER audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW
DECLARE
v_action VARCHAR2(20);
BEGIN
IF INSERTING THEN
v_action := 'INSERT';
ELSIF UPDATING THEN
v_action := 'UPDATE';
ELSIF DELETING THEN
v_action := 'DELETE';
END IF;
INSERT INTO audit_log (table_name, action, action_time)
VALUES ('emp', v_action, sysdate);
END;
/
SQL 语法兼容
DUAL 表
SELECT sysdate FROM dual;
SELECT 1+1 FROM dual;
SELECT USER FROM dual;
ROWNUM
-- 分页查询
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
SELECT * FROM emp ORDER BY sal DESC
) t WHERE ROWNUM <= 20
) WHERE rn > 10;
CONNECT BY 层次查询
SELECT employee_id, manager_id, LPAD(' ', LEVEL*2) || ename AS org_chart
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;
MERGE INTO
MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.name = s.name, t.value = s.value
WHEN NOT MATCHED THEN
INSERT (id, name, value) VALUES (s.id, s.name, s.value);
UPSERT
INSERT INTO emp (id, name, sal) VALUES (1, '张三', 5000)
ON CONFLICT (id) DO UPDATE SET sal = EXCLUDED.sal;
迁移评估清单
从 Oracle 迁移到 Vastbase G100 前,建议按以下清单逐项评估:
| 评估项 | 检查内容 | 风险等级 |
|---|---|---|
| 数据类型 | 检查是否使用了 Vastbase 不支持的类型 | 低 |
| 存储过程 | PL/SQL 语法差异、动态 SQL 兼容性 | 中 |
| 触发器 | 复合触发器、INSTEAD OF 触发器 | 中 |
| 包 | 包变量、初始化块 | 低 |
| 自定义类型 | RECORD 类型、对象类型、集合类型 | 中 |
| DBMS_LOB | LOB 操作接口完整性 | 低 |
| DBMS_OUTPUT | 输出缓冲区行为 | 低 |
| UTL_FILE | 文件操作接口 | 中 |
| DBMS_SCHEDULER | 作业调度 | 高 |
| 自定义聚合函数 | ODCIAggregate 接口 | 高 |
| Java 存储过程 | 数据库内嵌 Java | 不支持 |
| 外部表 | ORACLE_LOADER、ORACLE_DATAPUMP | 高 |
| 物化视图 | 刷新策略、查询重写 | 中 |
高风险项:DBMS_SCHEDULER 调度、外部表、Java 存储过程是迁移中最容易出问题的部分。建议提前评估替代方案。
迁移工具
Vastbase 提供配套迁移工具 VDS(Vastbase Data Studio),功能包括:
- 结构迁移:自动转换 Oracle DDL 为 Vastbase 语法
- 数据迁移:全量/增量数据迁移
- 应用适配:自动识别不兼容 SQL 并给出修改建议
- 校验工具:迁移前后数据一致性校验
建议迁移流程:
- 使用 VDS 扫描 Oracle 数据库,生成兼容性报告
- 评估高风险项,制定适配方案
- 使用 VDS 自动迁移结构
- 手动适配不兼容的存储过程和触发器
- 执行数据迁移
- 应用适配测试
- 性能调优
总结
Vastbase G100 的 Oracle 兼容性在国产数据库中属于第一梯队。1799 页兼容性手册覆盖了绝大多数 Oracle 特性,常见的数据类型、函数、PL/SQL 语法基本可以无缝迁移。
需要重点关注的风险点:
- DBMS_SCHEDULER:调度功能可能需要改用操作系统 crontab 或应用层调度
- Java 存储过程:完全不支持,需要外移到应用层
- 外部表:接口和格式有差异,需要适配
- 自定义聚合函数:接口不完全兼容,可能需要重写
整体评估,对于标准 OLTP 业务系统,Vastbase G100 的 Oracle 兼容性可以覆盖 90%+ 的场景。剩余 10% 需要手动适配的部分,迁移工具能提供详细的修改建议,工作量可控。

