ITPub博客

首页 > 数据库 > 国内数据库 > 一套官方 Skill,两套兼容库:我把示例 SQL 跑了一遍

一套官方 Skill,两套兼容库:我把示例 SQL 跑了一遍

原创 国内数据库 作者:sjw1933 时间:2026-08-29 23:11:50 0 删除 编辑

电科金仓在 Gitee 上发布了 kes-skills,包含 31 个供 AI 助手调用的技能。按官方介绍,安装后可以由智能体根据任务调用相应的技能。

我手上有两套金仓库,分别采用 Oracle 和 MySQL 兼容模式。8 月 26 日,我拿 kes-skills 里的示例做了一轮对照测试:先执行原文中的 SQL,遇到报错再尝试改写,记录两套库的执行结果。

测试时,我通过 ksql 执行 SQL,在命令行验证部分运维操作,没有接入智能体。

测试环境

两套金仓库和用来对照的 Oracle 12c 在同一台机器上。

项目 Oracle 兼容库 MySQL 兼容库 同机 Oracle 12c
数据库版本 KingbaseES V009R002C014 KingbaseES V009R003C018 Oracle 12.1.0.1 Enterprise Edition
database_mode oracle mysql 不适用
监听端口 54322 54323 未列出
初始化 initdb —dbmode=oracle initdb -m mysql 不适用
数据目录 /home/kingbaseo/data /home/kingbasemy/data 未列出
max_connections 100 100 未列出
shared_buffers 128MB 128MB 未列出
work_mem 4MB 4MB 未列出
sys_stat_statements.track none none 不适用
客户端 ksql V009R002C014 ksql V009R003C018 sqlplus / as sysdba

两套库分别使用各自安装目录下的 Server/bin 和 Server/lib,通过 ksql 连接 127.0.0.1,用户为 system,库名为 test。测试表统一以 skill_lab_ 开头,测试结束后删除。整个过程没有修改 kingbase.conf,也没有重启数据库。

两套库的版本不同,下面的执行差异也可能与版本有关,不能全部归因于兼容模式。

测试范围如下:

技能 测试内容
kes-oracle-compat SHOW oracle_compatible、NVL、DECODE、SYSDATE、dual、空串、ROWNUM、ADD_MONTHS、NUMBER/VARCHAR2、CONNECT BY、序列
kes-core sys_tables、RANK、递归 CTE、RANGE 分区、json/jsonb、ON CONFLICT
kes-plsql 技能页匿名块、DO 块、CREATE FUNCTION
kes-user-mgmt CREATE USER、授权、只读账号 SELECT/INSERT
kes-index-design BTree、部分索引、EXPLAIN
kes-backup sys_tablespace_size、sys_dump 及恢复
kes-db-optim SHOW shared_buffers / work_mem / max_connections、ANALYZE
kes-sql-tuning、kes-monitoring EXPLAIN、统计视图、KWR 函数名

这次实验不涉及 Java、Python 连接、Docker 安装、HA、KDTS,以及 kes-migration、 kes-vector、 kes-mcp 和 KRB/KRC/PITR。

kes-oracle-compat:兼容参数与 Oracle 语法

kes-oracle-compat 中用下面这条命令查询兼容参数:

SHOW oracle_compatible;

我在两套库上执行,都报参数不存在:

ERROR:  unrecognized configuration parameter "oracle_compatible"

改用 SHOW database_mode,分别查到 oracle 和 mysql。

技能页的迁移对照表列出了几组替代写法:NVL 对应 COALESCE,DECODE 对应 CASE,CONNECT BY 对应 WITH RECURSIVE。我先按 Oracle 的写法执行,检查两套库的支持情况。下面摘录部分测试语句,省略了数据准备和序列创建过程。

SELECT NVL(NULL, 'x');SELECT DECODE(1, 1, 'yes', 'no');SELECT SYSDATE;SELECT * FROM dual;SELECT CASE WHEN '' IS NULL THEN 'empty_is_null' ELSE 'empty_is_empty' END;SELECT ROWNUM FROM (SELECT 1 AS a) t;SELECT ADD_MONTHS(DATE '2024-01-31', 1);CREATE TABLE skill_lab_ora (id NUMBER(10) PRIMARY KEY, name VARCHAR2(32));CREATE TABLE skill_lab_emp (empno int PRIMARY KEY, ename varchar(16), mgr int);SELECT empno, ename, mgr, LEVEL FROM skill_lab_empSTART WITH mgr IS NULL CONNECT BY PRIOR empno = mgr;SELECT skill_lab_seq.NEXTVAL; SELECT nextval('skill_lab_seq');
语句 Oracle 兼容库(54322) MySQL 兼容库(54323) 同机 Oracle 12c
NVL(NULL,’x’) x x x
DECODE(1,1,’yes’,’no’) yes ERROR: function DECODE(…) does not exist yes
SYSDATE 2026-08-26 09:42:17 2026-08-26 09:42:17 26-AUG-26
SELECT * FROM dual 一行 X 一行 X 一行
‘’ IS NULL empty_is_null empty_is_empty empty_is_null
ROWNUM 1 1 1
ADD_MONTHS(DATE ‘2024-01-31’,1) 2024-02-29 00:00:00 ERROR: function ADD_MONTHS(…) does not exist 未跑
NUMBER + VARCHAR2 成功 成功 未列出结果
CONNECT BY + LEVEL 4 行,lvl=1/2/2/3 4 行,一样 未列出结果
seq.NEXTVAL 1 然后 2 1 然后 2 未列出结果

在这套 Oracle 兼容库上,NVL、DECODE、CONNECT BY 都能执行。对这几个示例,没有必要按对照表改写,增加代码修改和评审的工作量。MySQL 兼容库支持这里的 CONNECT BY,但执行 DECODE 和 ADD_MONTHS 时报函数不存在,这两处需要改写。

空串的处理有区别。Oracle 兼容库和 Oracle 12c 把 '' 当作 NULL,MySQL 兼容库保留为空字符串。表中的 CASE 语句在两套库上执行成功,却进入了不同的分支。迁移时如果只检查是否报错,就会漏掉这种差异。业务中涉及 IS NULL、唯一约束或 NVL/COALESCE 的地方,还需要补充空串用例,核对处理结果。

Oracle 兼容库的 ADD_MONTHS 输出中包含 00:00:00。接口如果按字符串比较日期,需要核对这里的输出格式。

kes-core:递归 CTE 与 JSON 取值

这一部分测试了系统表查询、窗口函数、递归 CTE、分区、JSON 取值和 UPSERT。以下为语句节选,省略号处需补全后执行。

SELECT schemaname, tablename FROM sys_tables WHERE schemaname NOT LIKE 'sys%' LIMIT 5;SELECT RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) FROM ...;WITH RECURSIVE org AS (SELECT 1 AS id, NULL::int AS pid, 1 AS depth UNION ALL ...);CREATE TABLE skill_lab_sales (...) PARTITION BY RANGE (sold_at);SELECT '{"a":1}'::json ->> 'a';INSERT ... ON CONFLICT (id) DO UPDATE ...;
语句 Oracle 兼容库 MySQL 兼容库
sys_tables 有结果;public 下能看到业务表 有结果;过滤 sys% 后仍能查到 pg_catalog 的表
RANK() 窗口 3 行,排序正确 同样
递归 CTE(id 写成 int) 3 行 ERROR: column 1 has type integer in non-recursive term but type bigint overall
RANGE 分区插入 count=1 count=1
json ->> 1 ERROR: syntax error, unexpected IDENT_P at end of jsonpath input
jsonb ->> 1 1
ON CONFLICT v 变成 new v 变成 new

MySQL 兼容库的递归 CTE 报了类型不一致:非递归部分是 integer,整个 CTE 是 bigint。我将非递归部分的 id 显式转换为 bigint 后,执行通过,递归逻辑没有改动。

JSON 取值也遇到了报错。在 MySQL 兼容库上, ::json ->> 解析失败;将这个示例中的类型换成 jsonb 后,返回值为 1,与 Oracle 兼容库一致。

kes-plsql:匿名块和函数

技能页给出的匿名块是:

BEGIN
    DECLARE v_count INT;    SELECT count(*) INTO v_count FROM sys_tables;
    RAISE NOTICE '表数量: %', v_count;END;

我在两套库上执行这段代码,都在 DECLARE 处遇到语法错误。改成 DO $$ ... $$ 后执行通过,Oracle 兼容库输出 NOTICE cnt=129,MySQL 兼容库输出 cnt=125。

技能页的函数示例使用 CREATE OR ALTER,没有指定 LANGUAGE。我将示例改成 plpgsql 写法,创建函数后执行 SELECT skill_lab_bonus(15000,'A'),两套库都返回 3000.00。这里验证通过的是改写后的版本。

kes-user-mgmt:只读账号权限

我按技能页的步骤执行 CREATE USER、 GRANT CONNECT、 GRANT SELECT 和 REVOKE INSERT,再切换到只读账号 skill_lab_r,分别执行查询和插入操作。

操作 Oracle 兼容库 MySQL 兼容库
CREATE USER + GRANT SELECT 成功 成功
只读 SELECT count(*) 1 1
只读 INSERT ERROR: permission denied for table skill_lab_acl 同样

执行 REVOKE INSERT 时,两套库都提示 WARNING: unable to revoke privilege not granted。新建角色没有 INSERT 权限,因此没有可撤销的授权。切换账号后的测试结果也符合预期:查询成功,插入时报权限错误。测试结束后,我删除了账号和测试表。

kes-index-design:索引与执行计划

我准备了 200 行数据,建了 BTree 和部分索引,设置 enable_seqscan=off 后执行:

EXPLAIN SELECT * FROM skill_lab_idx WHERE name='n10';

两套库的执行计划中都有 Index Scan using idx_skill_lab_name。在 sys_indexes 中能查到 pkey、 idx_skill_lab_name 和 idx_skill_lab_active。

这条执行计划是在 enable_seqscan=off 的条件下得到的,可以确认查询能够使用 idx_skill_lab_name,但不能据此判断默认配置下的索引选择或性能收益。GIN/GiST 不在本次测试范围内。

kes-backup、kes-db-optim:单表恢复与参数检查

我查询了默认表空间大小,用 sys_dump 导出 skill_lab_dump,再通过 ksql -f 恢复。另外检查了 shared_buffers、 work_mem 和 max_connections,并执行 ANALYZE。

任务 Oracle 兼容库 MySQL 兼容库
sys_tablespace_size 901 MB 82 MB
sys_dump 后恢复 SELECT count(*) 1 1
dump 文件头 Dumped from database version 12.1 同类格式
ANALYZE 成功 成功

导出文件头中的 Dumped from database version 12.1 与 version() 查询到的 KES 版本号不同。登记数据库版本时,应以 version() 的结果为依据,或核对安装目录中的 KESRealPro。

本次备份恢复使用了一张只有一行数据的测试表,恢复后的行数与备份前一致,未验证完整数据库的恢复。

统计视图、KWR 与客户端连接

kes-monitoring 和 kes-sql-tuning 中使用的是 sys_stat_statements。两套库都安装了扩展,版本分别为 1.12 和 1.11, sys_stat_statements.track 均为 none。我也查询了 pg_stat_statements,两套库都报 relation does not exist。这里需要使用金仓的视图名,并检查 track 的采集设置。

对于 Skill 中的 CALL sys_kv_wrm_take_snapshot(),我用 to_regproc 查询,两套库都返回空值。不过, ps 中能看到 kwr collector 进程,配置中也 preload 了 sys_kwr。这些信息还不足以判断 KWR 功能是否可用,需要进一步核对本库提供的函数及调用方式。这次没有执行快照验证。

对照执行计划时,我还发现 EXPLAIN 文本中的 pg_class 显示为 _rel。

我还做了客户端交叉连接测试:用 Oracle 兼容库的 ksql 连接 54323,用 MySQL 兼容库的 ksql 连接 54322, SELECT version() 都执行成功,返回对端的服务端版本。因此,连接成功不能用来确认客户端路径配置正确。两套库的脚本需要分别配置 BIN、LIB、端口和用户,执行前核对服务端版本。

总结

这次实测中,只读账号、分区、窗口函数和单表备份恢复都得到了预期结果,kes-skills 中的这些示例可以作为开发和运维的参考。需要修改的地方也有:兼容参数、匿名块写法,以及 MySQL 兼容库上的部分函数和类型处理,都遇到了问题。

迁移对照表中的替代写法,也需要根据目标库取舍。这套 Oracle 兼容库已经支持本次测试中的 NVL、DECODE、CONNECT BY,保留原 SQL 可以减少改造工作。对于空串这类语法能执行、结果却有差异的情况,还需要通过业务回归确认影响。

如果后续更新这套 Skill,我建议在示例旁标注验证过的版本和兼容模式,并补齐建表语句、测试数据及预期结果。这样,无论手工执行还是交给智能体调用,使用者都有一份可供复测的完整示例,遇到差异也方便核对。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23825935/viewspace-3181035/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
11年数据库行业经验,Oracle ACE、PG ACE、OCM、IBM Certified DBA、MySQL OCP、PolarDB技术专家、KCP、PCTP、PCSD、达梦师资认证、PolarDB开源社区技术顾问、ITPUB认证专家、某高校外聘教师

注册时间:2019-05-05

  • 博文量
    295
  • 访问量
    300690