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數據庫中不能使用。報錯如下:

在master和自己創建的sqlserver數據庫中正常:


結論:執行結果一致,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;


結論:執行結果一致,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;


結論:執行結果一致,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;


結論:執行結果一致,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;


結論:執行結果不一致,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
/


結論:執行結果一致,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);


結論:執行結果一致,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
/


結論:執行結果一致,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
/


KingbaseES中不管是否使用動態sql,都能拋出了自定義錯誤消息。
下面是sqlserver中的處理:

sqlserver中直接拋出原始錯誤:對象名 tab 無效。

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
/


結論:執行結果一致,KingbaseES和SQLServer的語句缺少分號功能是兼容的。
6、創建表最后一個字段可加逗號
CREATE TABLE Employee (
EmployeeID INT PRIMARY KEY,
Name NVARCHAR(100),
HireDate DATE,
);


結論:執行結果一致,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
墨天輪:http://www.sunline.cc/u/15197
如有任何疑問,歡迎大家留言,共同探討~~~




