- 数据库
- 关系型数据库
【免费下载链接】IvorySQL
Open Source Oracle Compatible PostgreSQL.
IvorySQL 是一款开源的 Oracle 兼容 PostgreSQL 数据库,让 Oracle 应用可以低成本迁移到开源生态。本文精选 4 个最实用的 Oracle 行为兼容特性:MERGE 语句、WITH READ ONLY 只读视图、空串转 NULL 参数以及 ROWNUM 伪列,帮你快速上手 IvorySQL 的 Oracle 兼容模式,减少应用改造工作量。
一、为什么选择 IvorySQL 做 Oracle 迁移?
Oracle 应用向开源数据库迁移,最大的痛点是"行为差异":语法不支持、数据类型默认值不同、NULL 语义不一致。IvorySQL 在 PostgreSQL 内核之上做了大量兼容性改造,让熟悉的 Oracle 写法"开箱即用"。
本次实战涉及的特性源码与测试用例可参考:
- 解析器与 Oracle 兼容 GUC 参数:src/backend/parser/parse_merge.c、src/backend/utils/misc/ivy_guc.c
- Oracle 行为回归测试:src/oracle_test/regress/sql/
二、MERGE 语句:一条 SQL 完成批量数据同步
MERGE 是 Oracle 数据同步场景的"神器",可以把"匹配则更新/删除、不匹配则插入"的逻辑压缩进一条语句,避免先查再改的多轮交互。IvorySQL 完整支持该语法(含NOT MATCHED BY SOURCE/NOT MATCHED BY TARGET分支),解析逻辑实现在 src/backend/parser/parse_merge.c 中。
一个典型的"账户余额同步"示例:
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = t.balance + s.delta WHEN NOT MATCHED THEN INSERT (tid, balance) VALUES (s.sid, s.delta);执行效果:
| 场景 | 行为 |
|---|---|
| 源表与目标表键匹配 | 更新目标行(或按 WHEN 分支删除/置空) |
| 源表有、目标表没有 | 插入新行 |
| 目标表有、源表没有 | 可使用WHEN NOT MATCHED BY SOURCE单独处理 |
💡实战提示:在数仓加载、CDC 数据回放、对账修正等场景中,MERGE 可以把原来"SELECT 查差集 → 循环 UPDATE/INSERT"的存储过程逻辑直接改写为一条 SQL,性能与可维护性都更好。完整语法与错误分支行为可参考测试用例 src/oracle_test/regress/sql/merge.sql。
三、只读视图:一行 WITH READ ONLY 锁住数据出口
Oracle 视图常用来做"只读数据视图",IvorySQL 支持在 CREATE VIEW 中直接声明WITH READ ONLY:
CREATE VIEW ro_view AS SELECT * FROM t_ro WITH READ ONLY;行为要点(来自 src/oracle_test/regress/sql/ora_read_only_view.sql):
- ✅ 对只读视图执行
SELECT正常,INSERT/UPDATE/DELETE全部报错拦截; - ✅ 用
CREATE OR REPLACE VIEW替换为不带WITH READ ONLY的定义后,视图恢复可写——注意这是"替换后"才生效; - ⚠️
WITH READ ONLY与WITH CHECK OPTION互斥,同时声明会报错; - ✅ 递归视图(
RECURSIVE VIEW)同样允许声明只读。
🔒实战提示:把报表、BI 查询统一挂到WITH READ ONLY视图上,相当于给业务方加了一道"防误删"护栏,比单纯靠权限管理更直观。
四、空串转 NULL:一个 GUC 参数对齐 Oracle 语义
这是 Oracle 迁移中最高频的坑:在 Oracle 中''(空字符串)就是 NULL,而在原生 PostgreSQL 中空串是合法值,WHERE col = ''与WHERE col IS NULL查出的结果完全不同。
IvorySQL 提供了会话级开关,开启后客户端传入的空串会被自动当作 NULL 处理:
SET ivorysql.enable_emptystring_to_NULL = on;- 参数定义见 src/backend/utils/misc/ivy_guc.c;
- 转换逻辑实现在 src/backend/tcop/postgres.c,仅在 Oracle 兼容模式下生效。
开启后的典型行为差异:
INSERT INTO null_student (id, grade) VALUES (6, ''); SELECT * FROM null_student WHERE grade IS NULL; -- 能查到 id=6 的行📌迁移建议:迁移前先用一条 SQL 摸底受影响的表——SELECT count(*) FROM tbl WHERE col = '' AND col IS NOT NULL;然后在应用连接串或数据库级别打开该参数,即可让老 Oracle 应用中大量= ''的判断恢复原有语义。用例可参考 src/oracle_test/regress/sql/emptystring_to_null.sql。
五、加餐:ROWNUM 伪列快速上手
Oracle 老代码里随处可见WHERE ROWNUM <= 100这种分页写法。IvorySQL 在 Oracle 兼容模式下支持 ROWNUM 伪列,迁移脚本中的分页查询无需批量改写为LIMIT/OFFSET,相关行为验证见 src/oracle_test/regress/sql/rownum.sql。
六、兼容性参数速查表
| 特性 | 开关/语法 | 参考位置 |
|---|---|---|
| MERGE 语句 | MERGE INTO ... USING ... | src/backend/parser/parse_merge.c |
| 只读视图 | CREATE VIEW ... WITH READ ONLY | src/oracle_test/regress/sql/ora_read_only_view.sql |
| 空串转 NULL | SET ivorysql.enable_emptystring_to_NULL = on | src/backend/utils/misc/ivy_guc.c |
| ROWNUM 伪列 | Oracle 兼容模式直接可用 | src/oracle_test/regress/sql/rownum.sql |
七、总结
IvorySQL 的 Oracle 兼容能力不止于此,本文选取的 4 个特性覆盖了数据同步(MERGE)、数据安全(只读视图)、语义对齐(空串转 NULL)、**分页查询(ROWNUM)**四类最常见的迁移改造点。建议迁移项目中:
- 先以 Oracle 兼容模式跑通回归测试;
- 用
ivorysql.enable_emptystring_to_NULL等 GUC 参数批量对齐语义; - 把数据出口视图统一加上
WITH READ ONLY。
更多 Oracle 兼容行为可以翻阅 src/oracle_test/regress/sql/ 下的回归测试用例,每个用例都对应一类真实迁移场景。
- 数据库
- 关系型数据库
【免费下载链接】IvorySQL
Open Source Oracle Compatible PostgreSQL.
相关推荐
IvorySQL Oracle兼容语法完整指南:ROWNUM、ROWID、CONNECT BY层次查询与NLS配置实战
IvorySQL Oracle兼容语法完整指南:ROWNUM、ROWID、CONNECT BY层次查询与NLS配置实战 IvorySQL 是一款基于 Postg
数据库关系型数据库IvorySQL: 开源世界里的Oracle兼容之王
IvorySQL: 开源世界里的Oracle兼容之王 在数据库领域,选择一款既强大又具备广泛兼容性的解决方案实属不易。而今天,我们将要推荐的IvorySQL,正
Presto MERGE 语句完全指南:语法、语义、权限与 Iceberg 实战
Presto MERGE 语句完全指南:语法、语义、权限与 Iceberg 实战 MERGE 是 Presto 提供的"一条语句搞定更新、插入、删除"的数据集成
大数据数据库后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考