作者:Digital Observer(施嘉伟)
Oracle ACE Pro: Database
PostgreSQL ACE Partner
11年数据库行业经验,现主要从事数据库服务工作
拥有Oracle OCM、DB2 10.1 Fundamentals、MySQL 8.0 OCP、WebLogic 12c OCA、KCP、PCTP、PCSD、PGCM、OCI、PolarDB技术专家、达梦师资认证、数据安全咨询高级等认证
ITPUB认证专家、PolarDB开源社区技术顾问、HaloDB技术顾问、TiDB社区技术布道师、青学会MOP技术社区专家顾问、国内某高校企业实践指导教师
公众号:Digital Observer;CSDN:施嘉伟;ITPUB:sjw1933;墨天轮:Digital Observer;PGFans:施嘉伟。
一、测试背景
随着国产数据库的发展,SQL Server 用户在迁移至国产平台时,最关注的问题之一就是语法兼容性和功能支持。KingbaseES 作为具备“多语法引擎”能力的国产数据库,正在不断增强对主流数据库的兼容能力。
本次测试是针对 KingbaseES V009R004C01 版本的 SQL Server 兼容能力进行验证,重点评估其对 SQL Server 特性语法、数据类型、事务控制、索引重建等方面的支持程度。
二、测试环境说明
KingbaseES 版本:V009R004C012(X64_Linux)
SQL Server 版本:Microsoft SQL Server 2008 R2 (SP2) 10.50.4042.0 (X64)
三、测试步骤
1. 特殊数据类型与对象
ROWVERSION / TIMESTAMP
- 测试目标:验证
ROWVERSION(或 TIMESTAMP)在表中的自动更新行为。
- SQL Server 特性:
ROWVERSION 类型用于标识表的版本,每次更新行时会自动生成新版本号。
CREATE TABLE test_rowversion (
id INT PRIMARY KEY,
version ROWVERSION
);
INSERT INTO test_rowversion (id) VALUES (1);
UPDATE test_rowversion SET id = 2 WHERE id = 1;
CREATE TABLE test_rowversion (
id INT PRIMARY KEY,
version ROWVERSION
);
INSERT INTO test_rowversion (id) VALUES (1);
UPDATE test_rowversion SET id = 2 WHERE id = 1;
> Affected rows: 1
Affected rows: 1
> 查询时间: 4.586s
 |
| 图1-1 |
- Kingbase 验证:模拟
ROWVERSION,验证表中数据每次更新时是否会自动生成新值。
CREATE TABLE test_rowversion (
id INT PRIMARY KEY,
version ROWVERSION
)
> OK
> 查询时间: 0.362s
INSERT INTO test_rowversion (id) VALUES (1)
> Affected rows: 1
> 查询时间: 0.186s
UPDATE test_rowversion SET id = 2 WHERE id = 1
> Affected rows: 1
> 查询时间: 0.132s
 |
| 图1-2 |
SQL_VARIANT
- 测试目标:检查
SQL_VARIANT 数据类型的兼容性,并确保可以存储不同类型的数据。
- SQL Server 特性:
SQL_VARIANT 可以存储不同类型的数据,如 INT, VARCHAR, DATE 等。
CREATE TABLE test_sql_variant (
id INT PRIMARY KEY,
value SQL_VARIANT
);
INSERT INTO test_sql_variant (id, value) VALUES (1, 100);
INSERT INTO test_sql_variant (id, value) VALUES (2, 'Hello');
INSERT INTO test_sql_variant (id, value) VALUES (3, '2025-07-22');
CREATE TABLE test_sql_variant (
id INT PRIMARY KEY,
value SQL_VARIANT
);
INSERT INTO test_sql_variant (id, value) VALUES (1, 100);
INSERT INTO test_sql_variant (id, value) VALUES (2, 'Hello');
INSERT INTO test_sql_variant (id, value) VALUES (3, '2025-07-22');
> Affected rows: 1
Affected rows: 1
Affected rows: 1
> 查询时间: 9.482s
 |
| 图1-3 |
- Kingbase 验证:检查是否支持通过类似的类型(如
JSON 或 TEXT)模拟 SQL_VARIANT 行为。
CREATE TABLE test_sql_variant (
id INT PRIMARY KEY,
value SQL_VARIANT
)
> OK
> 查询时间: 0.653s
INSERT INTO test_sql_variant (id, value) VALUES (1, 100)
> Affected rows: 1
> 查询时间: 0.167s
INSERT INTO test_sql_variant (id, value) VALUES (2, 'Hello')
> Affected rows: 1
> 查询时间: 0.099s
INSERT INTO test_sql_variant (id, value) VALUES (3, '2025-07-22')
> Affected rows: 1
> 查询时间: 0.134s
 |
| 图1-4 |
UNIQUEIDENTIFIER
- 测试目标:验证
UNIQUEIDENTIFIER 数据类型的兼容性,存储全局唯一标识符(GUID)。
- SQL Server 特性:使用
NEWID() 生成唯一标识符。
CREATE TABLE test_uniqueidentifier (
id UNIQUEIDENTIFIER PRIMARY KEY
);
INSERT INTO test_uniqueidentifier (id) VALUES (NEWID());
CREATE TABLE test_uniqueidentifier (
id UNIQUEIDENTIFIER PRIMARY KEY
);
INSERT INTO test_uniqueidentifier (id) VALUES (NEWID());
> Affected rows: 1
> 查询时间: 1.100s
 |
| 图1-5 |
- Kingbase 验证:验证
UUID 类型与 SQL Server 的 UNIQUEIDENTIFIER 是否兼容,并比较生成的 GUID 是否符合要求。
CREATE TABLE test_uniqueidentifier (
id UNIQUEIDENTIFIER PRIMARY KEY
)
> OK
> 查询时间: 0.751s
INSERT INTO test_uniqueidentifier (id) VALUES (NEWID())
> Affected rows: 1
> 查询时间: 0.084s
 |
| 图1-6 |
SYSNAME
- 测试目标:模拟
SYSNAME 数据类型,通常用于存储对象的名称,如表名或列名。
- SQL Server 特性:
SYSNAME 实际上是 NVARCHAR(128),用于存储系统名称。
CREATE TABLE test_sysname (
sysname_col SYSNAME
);
INSERT INTO test_sysname (sysname_col) VALUES ('TestSystemName');
CREATE TABLE test_sysname (
sysname_col SYSNAME
);
INSERT INTO test_sysname (sysname_col) VALUES ('TestSystemName');
> Affected rows: 1
> 查询时间: 5.150s
 |
| 图1-7 |
- Kingbase 验证:使用
VARCHAR 或 TEXT 来模拟,并测试其兼容性。
CREATE TABLE test_sysname (
sysname_col SYSNAME
)
> OK
> 查询时间: 0.702s
INSERT INTO test_sysname (sysname_col) VALUES ('TestSystemName')
> Affected rows: 1
> 查询时间: 0.099s
 |
| 图1-8 |
2. SQL 语句支持
NOWAIT / SKIP LOCKED
- 测试目标:测试锁定行为,确保
NOWAIT 和 SKIP LOCKED 在并发情况下按预期工作。
- SQL Server 特性:
NOWAIT 用于在等待锁定时立即返回错误,而 SKIP LOCKED 会跳过已锁定的行。
BEGIN TRANSACTION;
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE NOWAIT;
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE SKIP LOCKED;
BEGIN TRANSACTION;
SELECT * FROM test_rowversion WITH (UPDLOCK, ROWLOCK, READPAST) WHERE id = 1;
COMMIT TRANSACTION;
BEGIN TRANSACTION;
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE NOWAIT;
> Line 2: FOR UPDATE clause allowed only for DECLARE CURSOR.
> [42000] [FreeTDS][SQL Server]Line 2: FOR UPDATE clause allowed only for DECLARE CURSOR. (1003)
> 查询时间: 0.023s
BEGIN TRANSACTION;
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE SKIP LOCKED;
> Line 2: FOR UPDATE clause allowed only for DECLARE CURSOR.
> [42000] [FreeTDS][SQL Server]Line 2: FOR UPDATE clause allowed only for DECLARE CURSOR. (1003)
> 查询时间: 2.288s
 |
| 图2-1 |
 |
| 图2-2 |
- Kingbase 验证:验证
FOR UPDATE NOWAIT 和 FOR UPDATE SKIP LOCKED 是否按预期工作。
BEGIN TRANSACTION
> OK
> 查询时间: 0.043s
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE NOWAIT
> Affected rows: 0
> 查询时间: 0.033s
BEGIN TRANSACTION
> OK
> 查询时间: 0.039s
SELECT * FROM test_rowversion WHERE id = 1 FOR UPDATE SKIP LOCKED
> Affected rows: 0
> 查询时间: 0.022s
 |
| 图2-3 |
 |
| 图2-4 |
FOR XML
- 测试目标:验证
FOR XML 子句,将查询结果转换为 XML 格式。
- SQL Server 特性:SQL Server 的
FOR XML 允许将查询结果格式化为 XML。
SELECT id FROM test_rowversion FOR XML PATH('row');
 |
| 图2-5 |
- Kingbase 验证:验证是否支持 XML 输出,并测试性能。
 |
| 图2-6 |
3. 列属性(GUID都没有生成)
ROWGUIDCOL
- 测试目标:测试
ROWGUIDCOL 列属性,该属性用于标识存储 GUID 的列,并确保其在数据插入时按预期工作。
- SQL Server 特性:
ROWGUIDCOL 是专门用于存储 GUID 的列属性,通常与 UNIQUEIDENTIFIER 一起使用。
CREATE TABLE test_rowguidcol2 (
id INT PRIMARY KEY,
guid_column UNIQUEIDENTIFIER ROWGUIDCOL DEFAULT NEWSEQUENTIALID()
);
INSERT INTO test_rowguidcol2 (id) VALUES (1);
 |
| 图3-1 |
- Kingbase 验证:测试是否能使用
UUID 列属性来模拟 ROWGUIDCOL,并测试插入时是否自动生成 GUID。
 |
| 图3-2 |
4. 索引重建
INDEX…REBUILD
- 测试目标:验证索引重建功能,确保能够重建已有索引。
- SQL Server 特性:
INDEX...REBUILD 用于重建索引。
CREATE INDEX idx_test_rowversion ON test_rowversion (id);
ALTER INDEX idx_test_rowversion REBUILD;
ALTER INDEX idx_test_rowversion ON test_rowversion REBUILD;
> OK
> 查询时间: 3.853s
- Kingbase 验证:测试索引重建命令
REBUILD INDEX 是否有效。
ALTER INDEX idx_test_rowversion ON test_rowversion REBUILD
> WARNING: Does not verify whether index is related to table
LINE 1: ALTER INDEX idx_test_rowversion ON test_rowversion REBUILD
^
> OK
> 查询时间: 0.215s
5. 事务与并发控制
隔离级别
- 测试目标:验证不同隔离级别的事务控制功能,确保支持
READ COMMITTED、SERIALIZABLE 等隔离级别。
 |
| 图5-1 |
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
COMMIT;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
COMMIT;
> OK
> 查询时间: 0.443s
 |
| 图5-2 |
- Kingbase 验证:测试事务隔离级别是否按预期工作
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
> WARNING: SET TRANSACTION can only be used in transaction blocks
> OK
> 查询时间: 0.080s
BEGIN TRANSACTION
> OK
> 查询时间: 0.023s
COMMIT
> OK
> 查询时间: 0.868s
 |
| 图5-3 |
五、评测结语与建议
本次测试结果表明,KingbaseES V9 在SQL Server的兼容能力方面表现良好,尤其是在特殊数据类型、SQL语句支持和列属性方面实现了较好的兼容。然而,在部分场景中存在一些改进的地方:
1、 提供更详细的兼容性文档,指导用户进行 SQL Server 到 KingbaseES 的迁移。
2、 持续增强“多语法引擎”的能力,以覆盖更多 SQL Server 特性和语法。
3、 针对测试中发现的警告和错误信息,进行深入分析并给出解决方案或替代方案。其中较为明显的是【图1-1】和图【1-2】,以及【图2-5】和图【2-6】的字段显示.
4、 也有做的较好的地方,sqlserver不支持的语法,KingbaseES V9可以执行,比如图【2-1】和【2-2】
