9 月的体验官活动已结束,10 月新一期金仓数据库产品体验官活动开启了,本期主题是“接口多兼容深度体验”。本期内容偏开发,实战型很强,建议大家提前着手准备。

#KINGBASE 如果你还没有金仓社区的账号,欢迎注册:https://bbs.kingbase.com.cn/register
记得填写邀请人:18185
前几期内容参考如下:
- 2024第一期-KES单机安装
- 2024第二期-KES连接使用
- 2024第三期-KES数据迁移
- 2024第四期-KES性能优化
- 2024第五期-KES RWC安装部署
- 2024第六期-KES扩容缩容
- 2025第一期-SQL Server兼容体验
- 2025第二期-MySQL兼容体验
- 2025第三期-Oracle兼容体验
正文开始。
准备数据库
本文使用的是 KingbaseES V009R001C010 的 Oracle 兼容模式,其他不多介绍。
kingbase# select version();
version
-------------------------
KingbaseES V009R001C010
(1 row)
kingbase# show database_mode;
database_mode
---------------
oracle
(1 row)
接下来介绍两个兼容点,以供参考。
LATERAL 连接
在 Oracle 中,LATERAL 关键字用于在查询中引用外部查询的列。它允许在子查询中使用外部查询的结果,从而实现更灵活的数据处理。
金仓数据库在 Oracle 兼容模式里 1:1 还原了语义,用户可直接使用 Oracle 的语法。
常见用法
LATERAL 主要用于关联子查询和处理复杂数据结构两个场景。
关联子查询
当子查询需要引用外部查询的列时,使用 LATERAL 可以使子查询能够访问外部查询的结果,实现关联查询。
假设有两个表:departments(部门表)和 employees(员工表),现在需要查询每个部门中工资最高的员工信息。
-- 创建示例表
CREATE TABLE departments (
dept_id NUMBER PRIMARY KEY,
dept_name VARCHAR2(100)
);
CREATE TABLE employees (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
salary NUMBER,
dept_id NUMBER
);
-- 插入示例数据
INSERT INTO departments (dept_id, dept_name) VALUES (1, 'HR');
INSERT INTO departments (dept_id, dept_name) VALUES (2, 'IT');
INSERT INTO employees (emp_id, emp_name, salary, dept_id) VALUES (1, 'Alice', 5000, 1);
INSERT INTO employees (emp_id, emp_name, salary, dept_id) VALUES (2, 'Bob', 6000, 1);
INSERT INTO employees (emp_id, emp_name, salary, dept_id) VALUES (3, 'Charlie', 7000, 2);
INSERT INTO employees (emp_id, emp_name, salary, dept_id) VALUES (4, 'David', 8000, 2);
-- 查询每个部门中工资最高的员工信息
SELECT d.dept_name, e.emp_name, e.salary
FROM departments d,
LATERAL (
SELECT emp_name, salary
FROM employees
WHERE dept_id = d.dept_id
ORDER BY salary DESC
FETCH FIRST 1 ROWS ONLY
) e;
结果输出:
dept_name | emp_name | salary
-----------+----------+--------
HR | Bob | 6000
IT | David | 8000
(2 rows)

处理复杂数据结构
在处理包含数组、嵌套表等复杂数据结构时,LATERAL 可以将这些结构展开,方便进行数据处理和分析。
需要注意的是,虽然 LATERAL 提供了强大的查询能力,无需再写 ROW_NUMBER() OVER (PARTITION BY ...) 那一大坨,但过度使用可能会导致性能下降。因为 LATERAL 子查询会为外部查询的每一行执行一次,所以在处理大量数据时需要谨慎使用。语法方面,LATERAL 关键字必须紧跟在子查询之前,并且子查询必须是一个表子查询。
select 语句 bulk collect into 子句
Oracle DBA 熟悉的 PL/SQL 批量取数语法,在金仓数据库中也支持了。
演示案例,创建测试表、准备数据。
create table test (
id number primary key,
val varchar2(20),
something_else varchar2(20));
insert into test (id, val, something_else) values (1,'test1','else');
insert into test (id, val, something_else) values (2,'test2','else');
insert into test (id, val, something_else) values (3,'test3','else');
insert into test (id, val, something_else) values (4,'test4','else');
运行匿名块,脚本零修改,直接跑通,无报错。
kingbase# DECLARE
kingbase-# CURSOR test_cur
kingbase-# IS
kingbase-# SELECT
kingbase-# id,
kingbase-# val
kingbase-# FROM
kingbase-# test
kingbase-# ;
kingbase-# type test_rt
kingbase-# IS
kingbase-# record
kingbase-# (
kingbase(# id test.id%type,
kingbase(# val test.val%type);
kingbase-# type test_rec_arr is table of test_rt index by pls_integer;
kingbase-# test_rec test_rec_arr;
kingbase-# BEGIN
kingbase-# OPEN test_cur;
kingbase-# LOOP
kingbase-# FETCH
kingbase-# test_cur bulk collect
kingbase-# INTO
kingbase-# test_rec limit 10;
kingbase-# NULL;
kingbase-# EXIT
kingbase-# WHEN test_rec.count = 0;
kingbase-# END LOOP;
kingbase-# CLOSE test_cur;
kingbase-# END;
kingbase-# /
ANONYMOUS BLOCK
总结
Oracle 语法兼容性是个系统工程,需要智力和体力,不是一朝一夕就能完成的,尤其是很多语法细节的处理,需要在更多场景下验证。下节内容,我们开始介绍金仓数据库的接口,看看换成金仓数据库后,代码零修改能否真的让程序跑起来。
Have a nice day ~ ☕
🌻 往期精彩 ▼
- 全球 Oracle ACE 社区突破 500 位成员
- 「合集」MySQL 8.x 系列文章汇总
- 星辰资讯 | Ti 星球新鲜事(2025.09)
- IvorySQL 4.6 发布:新增兼容 MongoDB 解决方案
- 金仓数据库 Oracle 兼容模式体验
- 崖山数据库 YAC 共享集群入门
- 新建群聊:崖山和ta的朋友们~
- 一文带你了解 KWDB 数据库
- KWDB MVP 计划正式启动!速来!
- 国产老兵“虚谷数据库”初探
- 对话晨章数据CTO张桓:中国企业出海需要更优质的合作伙伴
- 如果国产中间件也参与国测,会有哪些厂商和产品入围
- BIC-QA:国产数据库的“咖啡伴侣”
- 腾讯云数据库家族扩容:TDSQL 与 AI 共生进化
- 在 OpenCloudOS 上编译安装 OpenTenBase 5.0 数据库
- 向量数据库 VexDB 入门指南
- 慕了!慕了!TiDB、海量、虚谷…今年的中秋礼物都送了些啥?
– / END / –
👉 欢迎关注我的视频号

👉 这里有得聊
如果对国产基础软件(操作系统、数据库、中间件)感兴趣,可以加群一起聊聊。
关注微信公众号:少安事务所,后台回复[群],即可看到入口。
如果这篇文章为你带来了灵感或启发,请帮忙『三连』吧,感谢!ღ( ´・ᴗ・` )~




