跳到主要内容从 Oracle 到金仓 KES:PL/SQL 兼容性与 JSON 处理实战 | 极客日志SQL
从 Oracle 到金仓 KES:PL/SQL 兼容性与 JSON 处理实战
金仓 KES 数据库在 Oracle 迁移场景中展现高 PL/SQL 兼容性,支持存储过程、函数、包等核心特性。文章演示了基础语法、游标、异常处理及包管理的实现方式,并介绍了原生 JSON 数据类型的存储、查询与修改操作。此外,对比了内置、聚集与分析函数的兼容性,提供了迁移评估与性能调优建议,助力企业平滑过渡至国产数据库环境。
引言:PL/SQL 兼容性的重要性
在金融、政务等关键行业的数据库国产化替代浪潮中,Oracle 数据库的迁移是重中之重。其中,承载了核心业务逻辑的存储过程、函数、触发器等 PL/SQL 代码,因其复杂性和对数据库引擎的强依赖性,常常成为迁移路上最大的挑战。金仓 KES 数据库将高兼容度的 PL/SQL 支持作为其核心能力,旨在降低迁移成本,保障业务平滑过渡。

一、金仓 KES 的 PL/SQL 引擎:深度兼容 Oracle 语法
金仓 KES 的 PL/SQL 引擎在设计上高度兼容 Oracle,这意味着大部分 Oracle 的 PL/SQL 代码可以在 KES 中几乎不加修改地运行。
1.1 基础程序结构兼容
以下是一个典型的 Oracle PL/SQL 代码块,在 KES 中可以直接执行。
DECLARE
v_emp_id NUMBER(10) := 1001;
v_emp_name VARCHAR2(50);
v_salary NUMBER(10, 2);
v_bonus NUMBER(10, 2) := 0;
CURSOR cur_emp IS SELECT employee_name, salary FROM employees WHERE employee_id = v_emp_id;
BEGIN
OPEN cur_emp;
FETCH cur_emp INTO v_emp_name, v_salary;
CLOSE cur_emp;
IF v_salary > 10000 THEN
v_bonus := v_salary * 0.2;
ELSIF v_salary BETWEEN 5000
v_bonus : v_salary ;
v_bonus : v_salary ;
IF;
DBMS_OUTPUT.PUT_LINE( v_emp_name v_salary v_bonus);
EXCEPTION
NO_DATA_FOUND
DBMS_OUTPUT.PUT_LINE();
OTHERS
DBMS_OUTPUT.PUT_LINE( SQLERRM);
;
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- SQL 美化和格式化
在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。 在线工具,SQL 美化和格式化在线工具,online
- SQL转CSV/JSON/XML
解析 INSERT 等受限 SQL,导出为 CSV、JSON、XML、YAML、HTML 表格(见页内语法说明)。 在线工具,SQL转CSV/JSON/XML在线工具,online
- CSV 工具包
CSV 与 JSON/XML/HTML/TSV/SQL 等互转,单页多 Tab。 在线工具,CSV 工具包在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
AND
10000
THEN
=
*
0.15
ELSE
=
*
0.1
END
'员工:'
||
||
',薪资:'
||
||
',奖金:'
||
WHEN
THEN
'未找到对应的员工记录。'
WHEN
THEN
'发生错误:'
||
END
/
- DECLARE 块、BEGIN...END 块的结构完全一致。
- 数据类型(NUMBER, VARCHAR2)、游标定义和使用方式相同。
- 条件控制流(IF-THEN-ELSIF-ELSE)语法一致。
- 内置包 DBMS_OUTPUT 的用法完全相同,KES 提供了高兼容度的实现。
- 异常处理机制(EXCEPTION 块)和内置异常(如 NO_DATA_FOUND)得到支持。
1.2 存储过程与函数的创建与调用
存储过程和函数是 PL/SQL 的核心。KES 在创建语法、参数模式(IN, OUT, IN OUT)等方面提供了出色兼容。
CREATE OR REPLACE PROCEDURE sp_calculate_bonus(
p_emp_id IN NUMBER,
p_bonus_percentage IN NUMBER DEFAULT 0.1,
p_bonus_amount OUT NUMBER,
p_status OUT VARCHAR2
) IS
v_salary NUMBER;
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = p_emp_id;
p_bonus_amount := v_salary * p_bonus_percentage;
p_status := 'SUCCESS';
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_bonus_amount := 0;
p_status := 'ERROR: Employee not found.';
WHEN OTHERS THEN
p_bonus_amount := 0;
p_status := 'ERROR: ' || SQLERRM;
END sp_calculate_bonus;
/
DECLARE
v_amount NUMBER;
v_status VARCHAR2(100);
BEGIN
sp_calculate_bonus(p_emp_id => 1001, p_bonus_percentage => 0.15, p_bonus_amount => v_amount, p_status => v_status);
DBMS_OUTPUT.PUT_LINE('状态:' || v_status || ', 奖金金额:' || v_amount);
END;
/
1.3 包(Package)的完整支持
包是 Oracle PL/SQL 中用于封装相关函数、过程、变量的大型代码单元。KES 对此有完整的支持。
CREATE OR REPLACE PACKAGE pkg_employee_mgmt AS
g_max_salary CONSTANT NUMBER := 100000;
CURSOR cur_high_paid_emps RETURN employees%ROWTYPE;
FUNCTION get_avg_salary(p_dept_id NUMBER) RETURN NUMBER;
PROCEDURE update_employee_salary(p_emp_id IN NUMBER, p_new_salary IN NUMBER, p_rows_affected OUT NUMBER);
END pkg_employee_mgmt;
/
CREATE OR REPLACE PACKAGE BODY pkg_employee_mgmt AS
CURSOR cur_high_paid_emps RETURN employees%ROWTYPE IS
SELECT * FROM employees WHERE salary > 50000;
FUNCTION get_avg_salary(p_dept_id NUMBER) RETURN NUMBER IS
v_avg_sal NUMBER;
BEGIN
SELECT AVG(salary) INTO v_avg_sal FROM employees WHERE department_id = p_dept_id;
RETURN NVL(v_avg_sal, 0);
END get_avg_salary;
PROCEDURE update_employee_salary(p_emp_id IN NUMBER, p_new_salary IN NUMBER, p_rows_affected OUT NUMBER) IS
BEGIN
IF p_new_salary > g_max_salary THEN
RAISE_APPLICATION_ERROR(-20001, '薪资超过上限' || g_max_salary);
END IF;
UPDATE employees SET salary = p_new_salary WHERE employee_id = p_emp_id;
p_rows_affected := SQL%ROWCOUNT;
IF p_rows_affected = 0 THEN
RAISE NO_DATA_FOUND;
END IF;
END update_employee_salary;
END pkg_employee_mgmt;
/
BEGIN
DBMS_OUTPUT.PUT_LINE('部门平均薪资:' || pkg_employee_mgmt.get_avg_salary(10));
END;
/
二、超越兼容:金仓 KES 对现代数据格式(JSON)的强大支持
除了对传统 PL/SQL 的兼容,金仓 KES 也紧跟技术发展趋势,提供了对 JSON 数据类型的原生支持和丰富的 JSON 函数,使其能够轻松应对半结构化数据处理场景。
2.1 JSON 数据的存储与基本查询
KES 提供了 JSON 数据类型来高效存储 JSON 文档。
CREATE TABLE product_catalog (
product_id NUMBER PRIMARY KEY,
product_info JSON,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO product_catalog (product_id, product_info) VALUES (
1, '{ "name": "智能手机", "brand": "华为", "specs": {"screen": "6.5inch", "memory": "8GB", "storage": "256GB"}, "price": 5999.00, "in_stock": true, "tags": ["5G", "徕卡镜头", "快充"] }'
);
INSERT INTO product_catalog (product_id, product_info) VALUES (
2, '{"name": "平板电脑", "brand": "苹果", "price": 4999.00, "in_stock": false}'
);
SELECT product_id, product_info -> 'name' as product_name, product_info -> 'price' as price FROM product_catalog;
2.2 高级 JSON 函数与路径查询
KES 支持丰富的 JSON 函数,如 json_extract_path_text, jsonb_set, json_array_elements 等,用于复杂操作。
SELECT product_id, json_extract_path_text(product_info::jsonb, 'specs', 'memory') as memory_size,
product_info -> 'tags' as tags_array
FROM product_catalog
WHERE product_info -> 'brand' = '"华为"';
SELECT p.product_id, jt.*
FROM product_catalog p, JSON_TABLE(p.product_info, '$' COLUMNS (
name VARCHAR(100) PATH '$.name',
brand VARCHAR(50) PATH '$.brand',
price NUMBER PATH '$.price',
in_stock BOOLEAN PATH '$.in_stock'
)) AS jt;
UPDATE product_catalog SET product_info = jsonb_set(product_info::jsonb, '{price}', '5499.00'::jsonb)
WHERE product_id = 1;
UPDATE product_catalog SET product_info = jsonb_insert(product_info::jsonb, '{tags, 0}', '"新品"')
WHERE product_id = 2;
UPDATE product_catalog SET product_info = product_info::jsonb - 'in_stock'
WHERE product_id = 2;
三、内置函数、聚集函数与分析函数对比
KES 在函数方面也力求与 Oracle 对齐,减少了迁移过程中的代码重写工作。
| 函数类别 | Oracle 示例 | 金仓 KES 兼容情况 | 备注 |
|---|
| 内置函数 | TO_CHAR(sysdate, 'YYYY-MM-DD')
NVL(salary, 0)
DECODE(status, 'A', 1, 'B', 2, 0) | 高度兼容 | KES 支持绝大部分 Oracle 常用内置函数,DECODE 函数得到完全支持。 |
| 聚集函数 | AVG(salary)
COUNT(DISTINCT dept_id)
LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) | 高度兼容 | 标准聚集函数完全兼容。LISTAGG 等高级聚集函数在 KES 中同样可用。 |
| 分析函数 | ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC)
LAG(salary, 1) OVER (ORDER BY hire_date)
SUM(salary) OVER (PARTITION BY dept_id) | 高度兼容 | KES 对 Oracle 分析函数(窗口函数)的支持非常完善,语法完全一致,是复杂报表查询平滑迁移的保障。 |
SELECT employee_id, employee_name, department_id, salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) as dept_salary_rank,
SUM(salary) OVER (PARTITION BY department_id ORDER BY salary ROWS UNBOUNDED PRECEDING) as dept_cumulative_salary,
AVG(salary) OVER (PARTITION BY department_id) as dept_avg_salary
FROM employees
ORDER BY department_id, salary DESC;
总结与建议
通过以上深入的代码演示和分析,我们可以清晰地看到,金仓 KES 数据库在 PL/SQL 兼容性方面确实下足了功夫,能够有效支撑从 Oracle 数据库的平滑迁移:
- PL/SQL 核心语法高兼容:从基础块、游标、异常到包管理等高级特性,KES 提供了企业级的支持,保障了核心业务逻辑的复用。
- 现代数据处理能力:对 JSON 等半结构化数据的原生支持,使 KES 不仅能承接传统应用,还能满足现代应用开发的新需求。
- 全面的函数支持:内置函数、聚集函数、分析函数的广泛兼容,确保了 SQL 脚本和复杂查询的顺利迁移。
- 评估阶段:使用 KDTS 或 KDMS 迁移评估工具,对现有 Oracle 代码进行自动化兼容性评估,精准识别需修改的少量代码点。
- 测试阶段:在 KES 环境中进行充分的单元测试和集成测试,重点关注涉及复杂业务逻辑的存储过程和函数。
- 性能调优:利用 KES 的 RWC 读写分离集群或 Sharding 分库分表组件,对迁移后的应用进行针对性的性能优化。
数据库国产化替代是一项复杂的系统工程,选择一款在技术生态上高度兼容、在产品能力上持续创新的数据库至关重要。金仓 KES 凭借其在 Oracle 兼容性方面的深厚积累和对现代数据架构的支撑能力,是企业实现安全、平滑、高效迁移的可靠选择。