【金仓数据库产品体验官】Oracle兼容性深度体验:从SQL到PL/SQL,金仓KingbaseES如何无缝平替Oracle?

摘要: 作为一名长期使用Oracle数据库的开发者,近年来在国产化替代浪潮下,我开始关注并尝试国产数据库产品。近期有幸深度体验了电科金仓的KingbaseES(简称KES)数据库,其对Oracle的高度兼容性令我印象深刻。本文将围绕KES在SQL语法、PL/SQL编程、接口兼容等多个维度的Oracle兼容特性,分享我的真实体验。

目录

1. 下载安装部署

1.1 官方下载linux镜像

1.2 授权文件对比

1.3 挂载安装包

1.4 开始启动安装程序

1.5 接受许可协议

1.6 安装包选择

1.7 安装目录和数据目录设置

1.8 初始化数据库

1.9 安装完成

1.10 执行root.sh

1.11 查看已安装的版本信息

2. 使用体验

2.1 登录在线体验数据

2.2 体验数据类型

2.3 体验SQL语句 EXECUTE IMMEDIATE

2.4 体验SQL语句 BULK COLLECT INTO

2.5 体验PL/SQL类型:集合 (Collection)

2.6 伪列 (Pseudocolumns) - ROWID, LEVEL

3.体验报告


1. 下载安装部署

准备硬件:4核CPU、8GB内存和50GB存储空间

准备软件:KingbaseES支持通用X86_64、飞腾、鲲鹏、龙芯、申威等国产CPU硬件体系架构。 KingbaseES支持主流的64位Linux操作系统,如银河麒麟、中标麒麟、统信、欧拉、凝思、Deepin、中科方德、CentOS、Ubuntu等。

完成环境准备后,我们就可以开始正式安装KingbaseES数据库了。本文将详细介绍从获取安装包到初始化配置的完整过程。

1.1 官方下载linux镜像

访问电科金仓官网(KES-电科金仓官网),KingbaseEs数据库安装包(Oracle兼容)-->V9R1C10(Oracle兼容版) --> X64 Linux-->下载KingbaseES_V9R001C010B0003_Lin64_install.iso镜像,如下所示:

下载完成之后上传到自己要安装的服务器上,我这里的Ubuntu服务器,如下所示:

1.2 授权文件对比

对于下载的文件,建议进行完整性校验,以确保文件在传输过程中没有损坏:

# 计算下载文件的MD5校验和
md5sum /mnt/tools/kingbase/KingbaseES_V009R001C010B0003_Lin64_install.iso
# 计算下载文件的SHA1校验和
sha1sum /mnt/tools/kingbase/KingbaseES_V009R001C010B0003_Lin64_install.iso

我这里是md5验证,获取的值:2ce383a9047cf9f8e4d6fe59946ad2ed  跟官网对比

将计算结果与官网提供的校验值进行比对,确保完全一致后再进行后续操作。

1.3 挂载安装包

ISO格式的安装包需要先挂载才能访问其中的安装文件:

cd /mnt/tools/kingbase

mount KingbaseES_V009R001C010B0003_Lin64_install.iso ./KingbaseESV9

如上图所示,挂载安装包报错了,不用慌,是因为没有创建 KingbaseEsv9目录,创建之后重新执行即可。

mkdir -p ./KingbaseEsv9

1.4 开始启动安装程序

命令行安装支持中文和英文的文字提示。根据操作系统的语言设置会显示对应语言的提示信息。您可以执行如下命令查看操作系统的语言设置:

echo $LANG

如果系统显示值包含“zh_CN”,则为中文语言,安装程序会显示中文内容。否则,您可以执行如下命令修改语言设置为中文:

# 中文UTF-8
export LANG=zh_CN.UTF-8

# 英文UTF-8
export LANG=zh_US.UTF-8

特别注意:这里一定要查看自己系统的编码,不然后面安装的时候选择这个字符串没有,我亲自体验安装没有这个字符串,快安装完了提示报错(如下图所示),眼泪都要下来了,然后我重头来一次才安装成功。我这里的系统ubuntu,我这里设置伟en_US.UTF-8比较合适,因为中文有乱码不太适合,根据自己服务器情况选择。

进入到对应目录,开始运行安装

# 进入您挂载的安装包目录
cd /mnt/tools/kingbase/KingbaseESV9
# 再次执行安装命令
./setup.sh -i console

这里又报错了,遇到了一个常见的安装问题:KingbaseES 安装程序要求使用非 root 用户运行。这是出于安全和管理权限的考虑。别担心,这个问题很容易解决。

1、在 Linux 系统上,为数据库服务创建独立的用户是一个好习惯,如果上面已经创建了用户请授权后直接使用。

# 创建用户组
groupadd kingbase
# 创建用户并指定主组,同时创建家目录
useradd -g kingbase -m kingbase
# 为kingbase用户设置密码(请使用强密码)
passwd kingbase

系统会提示您输入并确认新密码,对应着操作即可。

2、将安装目录和数据目录的所有权赋予新创建的 kingbase 用户,确保该用户有足够的权限进行安装和写入数据。

# 假设您计划的安装目录是 /opt/Kingbase/ES/V9,数据目录是 /kingbase/data
mkdir -p /opt/Kingbase/ES/V9
mkdir -p /kingbase/data
# 更改目录所有者
chown -R kingbase:kingbase /opt/Kingbase
chown -R kingbase:kingbase /kingbase

3、切换到 kingbase 用户进行安装:

# 切换到 kingbase 用户,'-' 表示同时切换环境变量
su - kingbase

4、切换到 kingbase 用户后,再次进入安装脚本所在目录并执行安装命令。

# 进入您挂载的安装包目录
cd /mnt/tools/kingbase/KingbaseESV9
# 再次执行安装命令
./setup.sh -i console

1.5 接受许可协议

输入quit,按<ENTER>退出安装;

输入back,按<ENTER>返回前一屏幕;

直接按<ENTER>进行下一步操作。

若无特殊说明,以下各步骤皆与此相同。

1.6 安装包选择

如下图所示,看自己情况选择,新手推荐安装1全部

1.7 安装目录和数据目录设置

如上图所示,又遇到问题了,芭比Q了,不用慌,这是安装KingbaseES V9时遇到了许可证(license)文件路径的问题。错误信息表明安装程序期望一个具体的license文件,但您提供的 /opt/Kingbase/ES/V9 是一个目录路径。

回到官网这里下载对应的授权文件,然后上传到自己服务器对应的目录

然后继续执行,注意这里要指定bat文件,不能只到文件文件夹,如下图所示:

/opt/Kingbase/ES/V9/license.dat

第一次是上面命令,我这里第二次安装文件是:/data/Kingbase/ES/V9/license.dat

数据存储目录设置:注意这个目录一定要是空文件夹,我第一次安装目录是/kingbase/data

我重新安装目录是:/data/Kingbase/data

1.8 初始化数据库

默认端口:54321(可自定义)

默认账户为:system(可自定义)

密码(自定义)

默认字符集编码为:UTF8(可选 default、GBK、GB2312、GB18030)

  • 区域,可选值将随字符集编码选项发生变动。

    • 当字符集编码为 default 时,默认区域值为:default(可选 C)

    • 当字符集编码为 UTF8 时,默认区域值为:zh_CN.UTF-8(可选 en_US.UTF-8、C)

    • 当字符集编码为 GBK 时,默认区域值为:zh_CN.GBK(可选 C)

    • 当字符集编码为 GB2312 时,默认区域值为:zh_CN.GB2312(可选 C)

    • 当字符集编码为 GB18030 时,默认区域值为:zh_CN.GB18030(可选 C)

  • 默认大小写敏感为:是(可选否)

  • 默认数据块大小为:8k(可选16k、32k)

  • 默认身份认证方法为scram-sha-256(可选 scram-sm3,sm4,sm3)

  • 自定义参数(自定义),可自由输入任何值,作为初始化数据库的参数

    有关数据库初始化参数,详情可见《KingbaseES服务器应用参考手册》第2章

    自定义特殊参数:(如果输入值包含以下某一项,请注意特殊情况)

1.9 安装完成

出现以下字眼:successfully  恭喜您,安装成功!会得到一个启动root.sh命令

查看数据目录,会新增了很多文件,如下图:

同理,安装目录也会多了很多文件:

1.10 执行root.sh

如果想注册数据库服务为系统服务,您可以在安装并初始化数据库成功后,执行root.sh脚本来注册并启动数据库服务,具体步骤如下:

  1. 打开新终端;

  2. 切换到root用户;

  3. 运行${安装目录}/install/script/root.sh 。

    /opt/Kingbase/ES/V9/install/script/root.sh

如果想启动或停止数据库服务,进入${安装目录}/Server/bin目录执行如下命令:

#启动服务
sys_ctl -w start -D /data/Kingbase/data -l "/data/Kingbase/data/sys_log/startup.log"
#停止服务
sys_ctl stop -m fast -w -D /data/Kingbase/data

1.11 查看已安装的版本信息

进入${安装目录}/Server/bin目录,执行

cd /kingbase/data/KESRealPro/V009R001C010/Server/bin

./kingbase -V;

可以看到kingbase (KingbaseES) V009R001C010,说明安装跟我们下载的版本一致!

这个是安装整个流程总结,更多请查看官方文档:4. 安装KingbaseES — KingbaseES(Oracle兼容版)产品手册 

2. 使用体验

2.1 登录在线体验数据

# 切换到kingbase用户
su - kingbase
 
# 连接数据库
ksql -U SYSTEM -d test -p 54321
 

# 上面如果没设置系统ksql命令,可以指定到安装目录执行

/kingbase/data/KESRealPro/V009R002C012/Server/bin/ksql -U SYSTEM -d test -p 54321

上面要输入密码,我上面安装设置的密码:qwe123!@#  每个人的设置密码会不一样,大家根据自己安装数据即可。

2.2 体验数据类型

Oracle的INTERVAL类型处理时间差很方便,KES也支持。我们来试试:

-- 1. 创建一个测试表,包含YMINTERVAL和DSINTERVAL类型
CREATE TABLE test_interval (
    id NUMBER PRIMARY KEY,
    description VARCHAR2(100),
    years_months YMINTERVAL,  -- 年-月间隔
    days_seconds DSINTERVAL   -- 日-秒间隔
);

-- 2. 插入一些测试数据
INSERT INTO test_interval VALUES (1, '一年零三个月', INTERVAL '1-3' YEAR TO MONTH, INTERVAL '0 0:0:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (2, '十天十二小时', INTERVAL '0-0' YEAR TO MONTH, INTERVAL '10 12:0:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (3, '五小时三十分钟', INTERVAL '0-0' YEAR TO MONTH, INTERVAL '0 5:30:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (4, '两年', INTERVAL '2-0' YEAR TO MONTH, INTERVAL '0 0:0:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (5, '一百秒', INTERVAL '0-0' YEAR TO MONTH, INTERVAL '0 0:0:60' DAY TO SECOND); -- 注意:秒数超过60会被自动转换


INSERT INTO test_interval VALUES (6, '一年零三个月', INTERVAL '1-3' YEAR TO MONTH, INTERVAL '0 0:0:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (7, '十天十二小时', INTERVAL '0-0' YEAR TO MONTH, INTERVAL '10 12:0:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (8, '五小时三十分钟', INTERVAL '0-0' YEAR TO MONTH, INTERVAL '0 5:30:0' DAY TO SECOND);
INSERT INTO test_interval VALUES (9, '两年', INTERVAL '2-0' YEAR TO MONTH, INTERVAL '0 0:0:0' DAY TO SECOND);

-- 3. 查询验证数据
SELECT id, description, years_months, days_seconds FROM test_interval order by id;

-- 4. 尝试进行简单的间隔计算 (例如,将年月间隔加到日期上)
-- 假设当前日期是 2024-01-SELECT SYSDATE, SYSDATE + years_months AS future_date_from_ym, SYSDATE + days_seconds AS future_date_from_ds FROM test_interval WHERE id = 1;

体验结果: 表成功创建,数据插入无误,查询能显示INTERVAL类型的值,并且日期计算逻辑符合预期。

2.3 体验SQL语句 EXECUTE IMMEDIATE

EXECUTE IMMEDIATE, USING, RETURNING INTO,这部分主要在PL/SQL块里操作,模拟动态SQL和返回值获取:

-- 1. 首先,创建一个简单的测试表
CREATE TABLE test_dynamic_sql (
    id tinyint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, -- 使用自增主键
    name VARCHAR2(50),
    created_date DATE DEFAULT SYSDATE
);

DO $$
DECLARE
    v_name VARCHAR2(50) := 'Static Test User';
    v_inserted_id NUMBER;
BEGIN
    -- 尝试插入
    INSERT INTO test_dynamic_sql (name) VALUES (v_name);
    -- 尝试查询刚插入的ID (方法可能不安全,仅演示)
    SELECT id INTO v_inserted_id FROM test_dynamic_sql WHERE name = v_name ORDER BY id DESC LIMIT 1;
    -- 注意:这里无法像PL/SQL IDE那样直接输出v_inserted_id到终端
    -- 但查询本身会执行
END;
$$;
-- 注意:上面使用的是PostgreSQL风格的匿名代码块语法 (DO $$ ... $$;)
-- KES Oracle模式下,可能需要Oracle风格的匿名块语法,但需要ksql明确支持
-- Oracle风格匿名块 (如果ksql支持,通常需要以 / 结尾):

2.4 体验SQL语句 BULK COLLECT INTO

-- 1. 创建一个包含较多数据的测试表,使用KES内置的RANDOM()函数替代DBMS_RANDOM
CREATE TABLE bulk_test_data AS
SELECT LEVEL AS id,
       'Name_' || LEVEL AS name,
       -- 使用 RANDOM() 生成0-1之间的数,然后缩放到1-100
       (RANDOM() * 99 + 1)::INTEGER AS score 
       -- RANDOM() * 99 产生 0 到 98.999... 之间的数
       -- 加 1 产生 1 到 99.999... 之间的数
       -- ::INTEGER 将其转换为整数 (1 到 99 或 100)
FROM DUAL
CONNECT BY LEVEL <= 100; -- 生成100条测试数据

-- 2. 查看生成的数据,确认表创建和数据插入成功
SELECT * FROM bulk_test_data ORDER BY id LIMIT 5; -- 只看前5条确认格式
SELECT COUNT(*) AS total_records FROM bulk_test_data; -- 确认总共有100条

--  创建一个匿名PL/SQL块来演示BULK COLLECT INTO
DECLARE
    TYPE t_id_list IS TABLE OF NUMBER; -- 定义一个NUMBER类型的集合
    TYPE t_name_list IS TABLE OF VARCHAR2(50);
    TYPE t_score_list IS TABLE OF NUMBER;

    v_ids t_id_list; -- 声明集合变量
    v_names t_name_list;
    v_scores t_score_list;
BEGIN
    -- 3. 使用BULK COLLECT INTO一次性将多行数据查询到集合中
    SELECT id, name, score
    BULK COLLECT INTO v_ids, v_names, v_scores -- 一次性赋值给三个集合
    FROM bulk_test_data
    WHERE score > 50 -- 查询分数大于50的记录
    ORDER BY id; -- 为了演示,按ID排序

    -- 4. 输出集合中的数据量和部分内容
    DBMS_OUTPUT.PUT_LINE('查询到 ' || v_ids.COUNT || ' 条分数大于50的记录:');
    FOR i IN 1 .. LEAST(5, v_ids.COUNT) LOOP -- 只打印前5条或全部(如果少于5条)
        DBMS_OUTPUT.PUT_LINE('ID: ' || v_ids(i) || ', Name: ' || v_names(i) || ', Score: ' || v_scores(i));
    END LOOP;

END;

预期结果: PL/SQL块成功执行,DBMS_OUTPUT.PUT_LINE打印出查询到的记录总数和部分记录详情,展示了BULK COLLECT高效获取多行数据的能力。

2.5 体验PL/SQL类型:集合 (Collection)

上面的BULK COLLECT已经用到了集合,我们再单独看看集合的基本操作:

DECLARE
    TYPE t_number_array IS VARRAY(10) OF NUMBER; -- VARRAY: 可变长数组,最大长度10
    TYPE t_name_table IS TABLE OF VARCHAR2(50);  -- TABLE: 表类型集合,长度可变

    v_nums t_number_array := t_number_array(); -- 初始化VARRAY
    v_names t_name_table := t_name_table();    -- 初始化TABLE
BEGIN
    -- 1. 操作VARRAY
    v_nums.EXTEND(3); -- 扩展VARRAY长度
    v_nums(1) := 100;
    v_nums(2) := 200;
    v_nums(3) := 300;

    DBMS_OUTPUT.PUT_LINE('VARRAY v_nums 内容:');
    FOR i IN 1 .. v_nums.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE('  Index ' || i || ': ' || v_nums(i));
    END LOOP;

    -- 2. 操作TABLE
    v_names.EXTEND; -- 扩展TABLE长度
    v_names(v_names.LAST) := 'Alice'; -- LAST获取最后一个索引
    v_names.EXTEND;
    v_names(v_names.LAST) := 'Bob';
    v_names.EXTEND;
    v_names(v_names.LAST) := 'Charlie';

    DBMS_OUTPUT.PUT_LINE('TABLE v_names 内容:');
    FOR i IN 1 .. v_names.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE('  Index ' || i || ': ' || v_names(i));
    END LOOP;

    -- 3. 尝试删除TABLE中的元素 (VARRAY不支持DELETE方法)
    v_names.DELETE(2); -- 删除索引为2的元素 (Bob)
    DBMS_OUTPUT.PUT_LINE('删除索引2后,TABLE v_names 内容 (注意稀疏性):');
    FOR i IN v_names.FIRST .. v_names.LAST LOOP -- 使用FIRST和LAST遍历,注意处理空洞
        IF v_names.EXISTS(i) THEN -- 检查索引i是否存在
            DBMS_OUTPUT.PUT_LINE('  Index ' || i || ': ' || v_names(i));
        ELSE
            DBMS_OUTPUT.PUT_LINE('  Index ' || i || ': (NULL - 已删除)');
        END IF;
    END LOOP;

END;
/

预期结果: PL/SQL块成功执行,DBMS_OUTPUT.PUT_LINE打印出VARRAY和TABLE的创建、赋值、删除操作的结果,展示了集合的基本用法。

2.6 伪列 (Pseudocolumns) - ROWID, LEVEL

伪列是Oracle/KES提供的特殊列,无需定义即可使用:

-- 1. 测试ROWID (注意:KES的ROWID实现可能与Oracle略有不同,但基本功能应存在)
CREATE TABLE test_rowid AS SELECT LEVEL AS id, 'Item_' || LEVEL AS name FROM DUAL CONNECT BY LEVEL <= 5;

SELECT id, name, ROWID FROM test_rowid; -- 查询每行的ROWID

-- 2. 测试LEVEL (常用于层次查询,这里用CONNECT BY模拟)
SELECT LEVEL, id, name
FROM test_rowid
START WITH id = 1 -- 从ID=1的行开始
CONNECT BY PRIOR id = id - 1 AND LEVEL <= 3; -- 构建一个简单的父子关系,限制层级为3

-- 3. 清理测试表 (可选)
-- DROP TABLE test_rowid;

预期结果: 查询能成功返回结果,并包含ROWIDLEVEL列的值。

以上就是本次实操体验的脚本合集。通过这些脚本,我们可以直观地感受到KES在数据类型、SQL语法、PL/SQL以及伪列等方面对Oracle的兼容性。希望能对您有所帮助!记得在执行前确认KES的Oracle兼容模式已开启哦!

3.体验报告

针对体验报告,我还专门制作了一套网站,欢迎大家来访,有什么建议欢迎评论区留言哦!

https://vxc7rgei3tatg.ok.kimi.link/experience.html

 关于本文,博主还写了相关文章,欢迎关注《电科金仓》分类:

第一章:基础与入门

1、【金仓数据库征文】政府项目数据库迁移:从MySQL 5.7到KingbaseES的蜕变之路

2、【金仓数据库征文】学校AI数字人:从Sql Server到KingbaseES的数据库转型之路

3、电科金仓2025发布会,国产数据库的AI融合进化与智领未来

4、国产数据库逆袭:老邓的“六大不敢替”被金仓逐一破解

5、《一行代码不改动!用KES V9 2025完成SQL Server → 金仓“平替”迁移并启用向量检索》

6、《赤兔引擎×的卢智能体:电科金仓如何用“三骏架构”重塑AI原生数据库一体机》

7、探秘KingbaseES在线体验平台:技术盛宴还是虚有其表?

8、破除“分布式”迷思:回归数据库选型的本质

9、KDMS V4 一键搞定国产化迁移:零代码、零事故、零熬夜——金仓社区发布史上最省心数据库迁移评估神器

10、KingbaseES V009版本发布:国产数据库的新飞跃

第二章:能力与提升

1、零改造迁移实录:2000+存储过程从SQL Server滑入KingbaseES V9R4C12的72小时

2、国产数据库迁移神器,KDMSV4震撼上线

3、在Ubuntu服务器上安装KingbaseES V009R002C012(Orable兼容版)数据库过程详细记录

4、金仓数据库迁移评估系统(KDMS)V4 正式上线:国产化替代的技术底气

5、Ubuntu系统下Python连接国产KingbaseES数据库实现增删改查

6、KingbaseES V009版本发布,新特性代码案例

7、Java连接电科金仓数据库(KingbaseES)实战指南

8、使用 Docker 快速部署 KingbaseES 国产数据库:亲测全过程分享

9、【金仓数据库产品体验官】Oracle兼容性深度体验:从SQL到PL/SQL,金仓KingbaseES如何无缝平替Oracle?

评论 184
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在走向自律

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值