暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

【金仓数据库产品体验官】KingbaseES(SQLServer兼容版)兼容性测试

原创 飞天 2025-09-14
539

KingbaseES(SQLServer兼容版)V9R4C12版本说明

KingbaseES(SQLServer兼容版)V9R4C12版本加入了更多针对各行业应用场景的定制化功能,助力企业实现平滑迁移和业务高效运行。该版本新增了对SQLServer若干系统视图和内置函数的支持,支持ICU库并对其进行了优化;支持更多的高级查询功能,包括FOR XML子句、PIVOT行列转换操作、GROUP BY子句中基于不同数据类型进行分组、DINSTICT子句与ORDER BY联合中列别名的使用等;新增DML操作触发更新统计信息功能,提升查询性能与增强系统的稳定性;新增临时表优化功能,提升了函数执行效率。在客户端编程接口方面,.Net驱动中新增了对SQL Server 中一些日期函数的支持,这些新功能可以支撑应用灵活处理各种日期运算场景。

该版本修复了对GBK编码支持、索引选项、SQL操作符、存储过程、.NET接口以及KStudio使用中的若干缺陷,为用户高效使用SQLServe兼容版的各项功能提供了有效的支撑与保障。

当前,金仓数据库KingbaseES已在医疗、海关、政务等领域打造了一系列替代SQL Server的典型案例,为千行百业的数字化转型升级提供持续服务。

本文主要是做KingbaseES(SQLServer兼容版)和 SQLServer数据库兼容性测试。

KingbaseES(SQLServer兼容版)单机部署

请参考前一篇文章:KingbaseES(SQLServer兼容版)单机部署

KingbaseES(SQLServer兼容版)和 SQLServer 数据库兼容性测试

SQL兼容

1、数据类型:ROWVERSION

该类型是自动生成的唯一二进制数字的数据类型。该类型存储大小为8个字节。接受NULL输入,固定以0x****************的8字节的16进制格式输出。timestamp类型为rowversion类型的同义词。

--创建测试表 CREATE TABLE students ( id int primary key, name VARCHAR(50), deptno int, rv ROWVERSION ); --插入数据 insert into students(id,name,deptno) values(1,'张三',10); insert into students(id,name,deptno) values(2,'李四',20); insert into students(id,name,deptno) values(3,'王五',30); insert into students(id,name,deptno) values(4,'王艳',10); insert into students(id,name,deptno) values(5,'颜小',20); --查询数据 select * from students;

注意:在master或者自己创建的数据库中都可以使用rowversion类型,在test数据库中不能使用。报错如下:
image.png

在master和自己创建的sqlserver数据库中正常:

image.png
image.png

结论:执行结果一致,KingbaseES和SQLServer的ROWVERSION数据类型是完全兼容的。

2、数据类型:SQL_VARIANT

sql_variant数据类型用于存储支持的各种数据类型。支持的基础数据类型范围见下表:

数据类型 数据类型类别
datetime2 日期和时间
datetime 日期和时间
smalldatetime 日期和时间
date 日期和时间
time 日期和时间
float(float8) 近似数值
real(float4) 近似数值
decimal(numeric) 精确数值
money 精确数值
bigint(int8) 精确数值
int(int4) 精确数值
smallint(int2) 精确数值
tinyint 精确数值
bit 精确数值
nvarchar Unicode
nchar Unicode
varchar Unicode
char(bpchar) Unicode
varbinary Binary
binary Binary
uniqueidentifier Uniqueidentifier

使用说明:

  • sql_variant数据类型支持作为表列,变量,函数参数和返回值使用。
  • 上表中描述的基础数据类型,都可以隐式转换为sql_variant类型,但不支持sql_variant类型隐式转换为其它类型。
  • sql_variant数据类型必须先转换为基本数据类型值,然后才能参与算数运算。
  • sql_variant数据支持导入导出。导出时如果指定–copy-binary参数,能够导出属性,导入后数据的属性信息不变。如果不指定–copy-binary参数时,导出仅备份数据,不导出属性信息,导入时数据的基础类型全部是varchar类型。
--创建测试表 CREATE TABLE TEST_SQL_VARIANT ( id INT IDENTITY PRIMARY KEY, var_col SQL_VARIANT ); -- 插入不同类型的数据 INSERT INTO TEST_SQL_VARIANT(var_col) VALUES (N'字符串文本'); INSERT INTO TEST_SQL_VARIANT(var_col) VALUES (12345678); INSERT INTO TEST_SQL_VARIANT(var_col) VALUES (3.14159); INSERT INTO TEST_SQL_VARIANT(var_col) VALUES (CAST('2023-10-01' AS DATE)); INSERT INTO TEST_SQL_VARIANT(var_col) VALUES (1); -- 查询数据 SELECT id, var_col, SQL_VARIANT_PROPERTY(var_col, 'BaseType') AS BaseType FROM TEST_SQL_VARIANT;

image.png
image.png

结论:执行结果一致,KingbaseES和SQLServer的SQL_VARIANT数据类型是兼容的。

3、数据类型:UNIQUEIDENTIFIER

UNIQUEIDENTIFIER类型是一个16字节的 GUID 类型。
NEWID()函数生成随机GUID,或NEWSEQUENTIALID()生成顺序GUID(减少索引碎片)。

-- 创建测试表 CREATE TABLE TEST_GUID ( ID INT PRIMARY KEY, GuidCol UNIQUEIDENTIFIER DEFAULT NEWID(), --NEWID()函数生成随机GUID Description NVARCHAR(50) ); -- 插入数据(显式指定GUID) INSERT INTO TEST_GUID (ID, GuidCol, Description) VALUES (1, '6F9619FF-8B86-D011-B42D-00C04FC964FF', 'Explicit GUID'), (2, DEFAULT, 'Auto-generated GUID'); -- 查询数据 SELECT * FROM TEST_GUID;

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer的UNIQUEIDENTIFIER是兼容的。

4、sql语句:top子句

--创建测试表 CREATE TABLE EMP ( empno NUMERIC(4) NOT NULL, ename VARCHAR(10), job VARCHAR(9), mgr NUMERIC(4), hiredate DATE, sal NUMERIC(7,2), comm NUMERIC(7,2), deptno NUMERIC(2) ); --插入数据 INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20); INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30); INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30); INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20); INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30); --查询数据 select top 3 * from emp;

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer的 top子句 是兼容的。

5、sql语句:index …rebuild 子句

--创建索引 create index idx_ename on emp(ename); --重建索引 alter index idx_ename rebuild; alter index idx_ename on emp rebuild;

image.png
image.png
结论:执行结果不一致,KingbaseES和SQLServer的 index …rebuild 子句是不兼容的。

T-SQL兼容测试

1、GO批处理语句

批处理语句GO是SQLServer的一个强大的工具。它可以帮助用户更好地组织和管理 SQL 脚本,提高脚本的可读性和可维护性,并增强错误处理和事务管理的能力以及执行效率。GO命令可以将 SQL 脚本中的语句分隔成多个逻辑上的批处理,允许用户将相关的语句组合在一起作为一个逻辑单元来执行。由于每个GO命令之前的语句被视为一个独立的批处理,这种错误隔离的特性使得调试和修复问题变得更加容易。另外GO命令所带来的事务管理能力有助于确保数据的完整性和一致性。而通过在GO命令后指定一个数字,可以重复执行前面的批处理语句指定的次数。这对于需要多次执行相同操作的场景非常有用。
SQLServer中,单个批处理语句集合会被编译为单一的执行计划被系统缓存,当再次执行时无需重新编译,从而极大地提升了SQL语句集的执行效率。
金仓数据库最新的SQLServer 兼容版,实现了对批处理命令GO语句的全面支持。无论是通过客户端工具(ksql、kstudio),还是从客户端编程接口,用户均可以在SQL层以及PLSQL层通过GO命令,对单条或多条SQL语句在数据库服务器端完成批量执行,从而继续享受GO命令带来的巨大便利与效率提升了。

create table testgo1(id int,sal numeric(7,2)); insert into testgo1 values(1,10000); insert into testgo1 values(2,20000); insert into testgo1 values(3,30000); create table testgo2(id int,sal numeric(7,2)); insert into testgo2 values(4,10000); insert into testgo2 values(5,20000); insert into testgo2 values(6,30000); \set SQLTERM / select * from testgo1 go select * from testgo2 /

image.png
image.png

结论:执行结果一致,KingbaseES和SQLServer的GO批处理语句是兼容的。

2、PRINT打印语句

create table emp2(id int,sal numeric(7,2)); insert into emp2 values(1,10000); insert into emp2 values(2,20000); insert into emp2 values(3,30000); insert into emp2 values(4,40000); insert into emp2 values(5,50000); insert into emp2 values(6,60000); PRINT '开始执行数据清理...'; DELETE FROM emp2 WHERE ID > 2; PRINT '数据清理完成,影响行数:' + CAST(@@ROWCOUNT AS VARCHAR);

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer的PRINT打印语句是兼容的。

3、RAISERROR错误处理语句

\set SQLTERM / BEGIN TRY IF NOT EXISTS (SELECT 1 FROM Employee) RAISERROR('表中无数据!', 16, 1); -- 严重级别16,状态1 END TRY BEGIN CATCH PRINT '错误信息:' + ERROR_MESSAGE(); END CATCH /

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer的RAISERROR错误处理语句兼容。

4、THROW错误处理语句

\set SQLTERM / BEGIN TRY INSERT INTO tab VALUES (1); -- tab表不存在,故意引发错误 END TRY BEGIN CATCH --THROW; -- 重新抛出原始错误 THROW 51000, '自定义错误消息', 1; -- 自定义错误 END CATCH /

image.png
image.png
KingbaseES中不管是否使用动态sql,都能抛出了自定义错误消息。

下面是sqlserver中的处理:
image.png
sqlserver中直接抛出原始错误:对象名 tab 无效。

image.png
sqlserver中使用动态sql后,抛出了自定义错误消息。

结论:执行结果稍有差异,KingbaseES和SQLServer的THROW错误处理语句兼容。

5、语句缺失分号

SQLServer支持SQL语句之间无分号分隔符。在 SQLServer Management Studio (SSMS) 中,默认情况下,用户可以在一个查询窗口中输入多个不带分号的 SQL 语句,并且可以一次执行这些语句。对于这种看似奇怪的“特性”,KingbaseES也在最新的SQLServer 兼容版本中实现了支持。

\set SQLTERM / CREATE TABLE emp3 ( EmployeeID INT PRIMARY KEY, Name NVARCHAR(100), HireDate DATE, ) select * from emp3 select * from emp2 /

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer的语句缺少分号功能是兼容的。

6、创建表最后一个字段可加逗号

CREATE TABLE Employee ( EmployeeID INT PRIMARY KEY, Name NVARCHAR(100), HireDate DATE, );

image.png
image.png
结论:执行结果一致,KingbaseES和SQLServer在创建表的时候,最后一个字段都可加逗号功能是兼容的。

总结

经过上述测试可见,KingbaseES(SQLServer 兼容版)与 SQLServer 的兼容性相当高,后续有时间再继续验证其他功能。

金仓数据库产品体验官活动链接

https://bbs.kingbase.com.cn/forumDetail?articleId=5262510af41971c328bd0a78dd8aa56a

官方文档链接

https://bbs.kingbase.com.cn/documentGuide?recId=bf40609a9c064fe3593c2040d4d899c8

关于作者

网名:飞天,墨天轮2024年度优秀原创作者,拥有 Oracle 10g OCM 认证、PGCE认证、MySQL 8.0 OCP认证以及OBCA、KCP、KCSM、ACP、YCP、磐维等众多国产数据库认证证书,目前从事Oracle、Mysql、PostgresSQL、磐维数据库管理运维工作,喜欢结交更多志同道合的朋友,热衷于研究、分享数据库技术。
微信公众号:飞天online
墨天轮:https://www.modb.pro/u/15197
如有任何疑问,欢迎大家留言,共同探讨~~~

最后修改时间:2025-09-15 10:10:29
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论