痛點: 不同資料庫 (Oracle, SQL Server, MySQL, PostgreSQL, DB2...) SQL 方言差異大:函數名、分頁語法、日期運算、DDL 型別映射... 導致:
方案: CowNewSQL 作為 **SQL 翻譯中介層**,開發者寫 **統一標準 SQL (CowNewSQL 方言)**,框架自動翻譯為目標資料庫原生 SQL。
| 標準寫法 (CowNewSQL) | SQL Server | MySQL | Oracle |
|---|---|---|---|
SELECT NOW() | SELECT GETDATE() | SELECT NOW() | SELECT SYSDATE FROM DUAL |
SELECT CURRENT_DATE | SELECT CAST(GETDATE() AS DATE) | SELECT CURDATE() | SELECT TRUNC(SYSDATE) FROM DUAL |
**兼容性:** 輸入 `SELECT GETDATE()` 也能正確翻譯為目標平台對應函數。
| 標準寫法 | SQL Server (2005-2012) | MySQL / PostgreSQL | Oracle (11g-) |
|---|---|---|---|
SELECT TOP 10 * FROM T_1 | SELECT TOP 10 * FROM T_1 | SELECT * FROM T_1 LIMIT 10 | SELECT * FROM T_1 WHERE ROWNUM <= 10 |
SELECT * FROM T_1 LIMIT 20 OFFSET 10 (標準 SQL:2008) | SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY ...) AS RN, * FROM T_1) T WHERE RN BETWEEN 11 AND 30 | SELECT * FROM T_1 LIMIT 20 OFFSET 10 | SELECT * FROM (SELECT ROWNUM RN, T.* FROM T_1) WHERE RN BETWEEN 11 AND 30 |
-- 原始 SQL (MySQL 不支援子查詢中 LIMIT)
DELETE FROM T_SaleInvoice
WHERE FId IN (SELECT TOP 5 FParentId FROM T_SaleInvoiceDetails)
-- CowNewSQL 翻譯後 (MySQL 可執行)
DELETE FROM T_SaleInvoice
WHERE FId IN (SELECT * FROM (SELECT FParentId FROM T_SaleInvoiceDetails LIMIT 0, 5) t_temp_sub)
引擎自動識別目標資料庫限制,採用 **衍生表包裝** 策略繞過限制。
-- 開發者統一使用
SELECT MONTHS_BETWEEN(date1, date2) FROM DUAL
-- MySQL 翻譯為組合函數
SELECT FLOOR((YEAR(date1) - YEAR(date2)) * 12 + (MONTH(date1) - MONTH(date2))
+ (DAY(date1) - DAY(date2)) / 31) FROM DUAL
使用者無需關心內部實現差異。
| 類別 | 支援項目 |
|---|---|
| DDL | CREATE TABLE, DROP TABLE, CREATE INDEX, DROP INDEX |
| DML | SELECT, INSERT, DELETE, UPDATE |
| 進階特性 | 子查詢 (相關/非相關), JOIN (INNER/LEFT/RIGHT/FULL), UNION/UNION ALL/INTERSECT/EXCEPT |
| 日期函數 | 當前日期/時間, 提取年/月/日/時/分/秒, 日期差異 (天/月/年), 日期加減間隔 |
| 數學函數 | ABS, PI, ROUND, CEIL/FLOOR, LOG/EXP, POWER, SQRT, RAND, SIGN, MOD |
| 字串函數 | SUBSTRING, LENGTH/CHAR_LENGTH, TRIM, UPPER/LOWER, CONCAT/||, REPLACE, LPAD/RPAD |
| 資料處理 | CAST/CONVERT (型別轉換), TO_CHAR/TO_DATE (格式化), COALESCE/NVL/IFNULL (空值處理), CASE WHEN |
// Maven 依賴 (假設發布至中央倉)
com.cownew
cownewsql
1.2.0 // 最新版本號
// 程式碼調用
CowNewSQLTranslator translator = new CowNewSQLTranslator(TargetDatabase.MYSQL);
String nativeSql = translator.translate("SELECT TOP 10 * FROM T_1 WHERE CREATE_TIME > NOW() - INTERVAL '7 DAY'");
// 產生: SELECT * FROM T_1 WHERE CREATE_TIME > DATE_SUB(NOW(), INTERVAL 7 DAY) LIMIT 10
| 產品 | 授權 | 支援資料庫 | 成熟度 | 備註 |
|---|---|---|---|---|
| CowNewSQL | 商業/開源雙模式 (官網確認) | Oracle, SQL Server, MySQL, PostgreSQL, DB2, Derby... | 生產就緒 (百條測試) | 中文文件友善、JDK 1.4+ 相容 |
| Apache Calcite | Apache 2.0 | 通用關係代數 + 適配器 (Cassandra, Druid, Elasticsearch...) | 頂級專案、極高 | 架構更宏大、學習曲線陡、適合構建查詢引擎 |
| Hibernate Dialect | LGPL | 主流關係型資料庫 | 成熟 | 僅限 HQL/Criteria → SQL,不支援任意 Native SQL 翻譯 |
| jOOQ | 商業/ASL 2.0 (社群版) | 20+ 資料庫 | 極高 | 類型安全 SQL 建構器、支援原生 SQL 解析/翻譯 (專業版) |
| MyBatis / SqlBuilder | Apache 2.0 | 主流 | 高 | 動態 SQL 模板、不具備方言翻譯能力 |
結語: CowNewSQL 以 **輕量級、專注 SQL 方言翻譯、相容舊版 JDK** 切入,為無法全面引入 JPA/jOOQ 的存量 Java 專案提供了低成本跨資料庫遷移路徑。建議團隊在 PoC 階段以真實業務 SQL 集測試驗證翻譯正確性後再決策採用。