
文章目录每日一句正能量一、前言语法差异是迁移的隐形杀手二、语法差异总览2.1 差异分类2.2 常见报错三、分页语法差异3.1 MySQL分页3.2 KaiwuDB分页四、插入更新语法差异4.1 ON DUPLICATE KEY UPDATE4.2 INSERT IGNORE4.3 REPLACE INTO五、字符串函数差异5.1 GROUP_CONCAT5.2 FIND_IN_SET5.3 SUBSTRING_INDEX5.4 其他字符串函数六、日期函数差异6.1 DATEDIFF6.2 DATE_FORMAT6.3 NOW()6.4 CURDATE()6.5 其他日期函数七、聚合函数差异7.1 标准聚合函数7.2 窗口函数八、类型转换函数差异8.1 CAST8.2 CONVERT九、存储过程差异9.1 存储过程语法9.2 变量声明9.3 游标十、其他语法差异10.1 反引号10.2 注释10.3 大小写敏感10.4 其他差异十一、自动化改造脚本11.1 SQL语句批量替换十二、总结每日一句正能量马年不是要你跑得最快而是要你跑得最远保持节奏不焦虑不回头。一、前言语法差异是迁移的隐形杀手前五篇文章我分享了MySQL迁移KaiwuDB的整体流程、工具使用和类型映射。有读者反馈“数据迁移成功了但应用跑起来报错一堆全是SQL语法问题。”确实数据迁移只是第一步SQL语法兼容性才是让应用真正跑起来的关键。MySQL和KaiwuDB虽然都支持SQL标准但在语法细节上存在不少差异。我这次迁移的是一个电商系统代码里有大几百条SQL语句。迁移过程中我整理了47处语法差异点本文就把这些经验分享出来希望能帮你少走弯路。二、语法差异总览2.1 差异分类类别数量影响程度分页语法1高插入更新1高字符串函数8中日期函数6中聚合函数3低类型转换4中其他函数5低存储过程3高其他语法10中2.2 常见报错ERROR: syntax error at or near LIMIT ERROR: function group_concat does not exist ERROR: function datediff does not exist ERROR: syntax error at or near ON DUPLICATE KEY三、分页语法差异3.1 MySQL分页-- MySQL分页SELECT*FROMordersLIMIT10OFFSET20;SELECT*FROMordersLIMIT20,10;-- 简写形式3.2 KaiwuDB分页-- KaiwuDB分页与MySQL相同SELECT*FROMordersLIMIT10OFFSET20;-- 注意不支持简写形式-- SELECT * FROM orders LIMIT 20, 10; -- 错误踩坑点1MySQL支持LIMIT offset, count简写形式KaiwuDB不支持。解决方案-- 统一使用标准形式SELECT*FROMordersLIMIT10OFFSET20;四、插入更新语法差异4.1 ON DUPLICATE KEY UPDATEMySQL支持ON DUPLICATE KEY UPDATEKaiwuDB不支持。-- MySQLINSERTINTOorders(id,order_no,status)VALUES(1,ORD001,1)ONDUPLICATEKEYUPDATEstatus1;解决方案使用UPSERT-- KaiwuDBUPSERTINTOorders(id,order_no,status)VALUES(1,ORD001,1);4.2 INSERT IGNOREMySQL支持INSERT IGNOREKaiwuDB不支持。-- MySQLINSERTIGNOREINTOorders(id,order_no)VALUES(1,ORD001);解决方案使用UPSERT-- KaiwuDBUPSERTINTOorders(id,order_no)VALUES(1,ORD001);4.3 REPLACE INTOMySQL支持REPLACE INTOKaiwuDB不支持。-- MySQLREPLACEINTOorders(id,order_no,status)VALUES(1,ORD001,1);解决方案使用UPSERT-- KaiwuDBUPSERTINTOorders(id,order_no,status)VALUES(1,ORD001,1);五、字符串函数差异5.1 GROUP_CONCATMySQL支持GROUP_CONCATKaiwuDB不支持。-- MySQLSELECTuser_id,GROUP_CONCAT(order_no)FROMordersGROUPBYuser_id;解决方案使用STRING_AGG-- KaiwuDBSELECTuser_id,STRING_AGG(order_no,,)FROMordersGROUPBYuser_id;5.2 FIND_IN_SETMySQL支持FIND_IN_SETKaiwuDB不支持。-- MySQLSELECT*FROMordersWHEREFIND_IN_SET(1,status);解决方案使用POSITION或LIKE-- KaiwuDBSELECT*FROMordersWHEREPOSITION(1INstatus)0;-- 或者SELECT*FROMordersWHEREstatusLIKE%1%;5.3 SUBSTRING_INDEXMySQL支持SUBSTRING_INDEXKaiwuDB不支持。-- MySQLSELECTSUBSTRING_INDEX(www.example.com,.,2);解决方案使用SPLIT_PART-- KaiwuDBSELECTSPLIT_PART(www.example.com,.,1)||.||SPLIT_PART(www.example.com,.,2);5.4 其他字符串函数MySQLKaiwuDB说明CONCAT_WSCONCAT_WS相同LENGTHLENGTH相同CHAR_LENGTHCHAR_LENGTH相同UPPERUPPER相同LOWERLOWER相同TRIMTRIM相同REPLACEREPLACE相同SUBSTRINGSUBSTRING相同LEFTLEFT相同RIGHTRIGHT相同LPADLPAD相同RPADRPAD相同INSTRPOSITION不同LOCATEPOSITION不同六、日期函数差异6.1 DATEDIFFMySQL支持DATEDIFFKaiwuDB不支持。-- MySQLSELECTDATEDIFF(2026-08-15,2026-08-01);解决方案使用减法-- KaiwuDBSELECTDATE2026-08-15-DATE2026-08-01;6.2 DATE_FORMATMySQL支持DATE_FORMATKaiwuDB不支持。-- MySQLSELECTDATE_FORMAT(created_at,%Y-%m-%d)FROMorders;解决方案使用TO_CHAR-- KaiwuDBSELECTTO_CHAR(created_at,YYYY-MM-DD)FROMorders;6.3 NOW()MySQL支持NOW()KaiwuDB支持。-- MySQL和KaiwuDB都支持SELECTNOW();6.4 CURDATE()MySQL支持CURDATE()KaiwuDB不支持。-- MySQLSELECTCURDATE();解决方案使用CURRENT_DATE-- KaiwuDBSELECTCURRENT_DATE;6.5 其他日期函数MySQLKaiwuDB说明DATE_ADD INTERVAL不同DATE_SUB- INTERVAL不同YEAREXTRACT(YEAR FROM …)不同MONTHEXTRACT(MONTH FROM …)不同DAYEXTRACT(DAY FROM …)不同HOUREXTRACT(HOUR FROM …)不同MINUTEEXTRACT(MINUTE FROM …)不同SECONDEXTRACT(SECOND FROM …)不同七、聚合函数差异7.1 标准聚合函数MySQLKaiwuDB说明COUNTCOUNT相同SUMSUM相同AVGAVG相同MAXMAX相同MINMIN相同7.2 窗口函数MySQL 8.0支持窗口函数KaiwuDB也支持。-- MySQL和KaiwuDB都支持SELECTuser_id,order_no,ROW_NUMBER()OVER(PARTITIONBYuser_idORDERBYcreated_at)asrnFROMorders;八、类型转换函数差异8.1 CASTMySQL和KaiwuDB都支持CAST但部分类型不同。-- MySQLSELECTCAST(123ASUNSIGNED);-- KaiwuDBSELECTCAST(123ASINT8);8.2 CONVERTMySQL支持CONVERTKaiwuDB不支持。-- MySQLSELECTCONVERT(123,UNSIGNED);解决方案使用CAST-- KaiwuDBSELECTCAST(123ASINT8);九、存储过程差异9.1 存储过程语法MySQL和KaiwuDB的存储过程语法有较大差异。-- MySQL存储过程DELIMITER$$CREATEPROCEDUREGetOrders(INuserIdINT)BEGINSELECT*FROMordersWHEREuser_iduserId;END$$DELIMITER;KaiwuDB存储过程-- KaiwuDB存储过程CREATEORREPLACEPROCEDUREGetOrders(userIdINT)AS$$BEGINSELECT*FROMordersWHEREuser_iduserId;END;$$LANGUAGEplpgsql;9.2 变量声明-- MySQLSETvar1;-- KaiwuDBDECLAREvarINT:1;9.3 游标-- MySQL游标DECLAREdoneINTDEFAULTFALSE;DECLAREcurCURSORFORSELECT*FROMorders;DECLARECONTINUEHANDLERFORNOTFOUNDSETdoneTRUE;OPENcur;FETCHcurINTO...;CLOSEcur;KaiwuDB游标-- KaiwuDB游标DECLAREcurCURSORFORSELECT*FROMorders;OPENcur;FETCHcurINTO...;CLOSEcur;十、其他语法差异10.1 反引号MySQL支持反引号KaiwuDB支持。-- MySQL和KaiwuDB都支持SELECT*FROMorders;10.2 注释MySQL和KaiwuDB都支持--和/* */注释。10.3 大小写敏感MySQL默认不区分大小写KaiwuDB区分。-- MySQL不区分大小写SELECT*FROMOrders;-- KaiwuDB区分大小写SELECT*FROMorders;-- 正确-- SELECT * FROM Orders; -- 错误10.4 其他差异MySQLKaiwuDB说明SHOW TABLESSHOW TABLES相同SHOW DATABASESSHOW DATABASES相同USE dbUSE db相同DESCRIBESHOW COLUMNS FROM不同EXPLAINEXPLAIN相同SELECT 1SELECT 1相同SELECT NOW()SELECT NOW()相同SELECT UUID()SELECT gen_random_uuid()不同十一、自动化改造脚本11.1 SQL语句批量替换#!/usr/bin/env python3# sql_transform.pyimportredeftransform_sql(sql):转换MySQL SQL到KaiwuDB SQL# 1. ON DUPLICATE KEY UPDATE - UPSERTsqlre.sub(rINSERT\sINTO\s(\w)\s*\(([^)])\)\s*VALUES\s*\(([^)])\)\s*ON\sDUPLICATE\sKEY\sUPDATE\s([^;]),rUPSERT INTO \1 (\2) VALUES (\3),sql,flagsre.IGNORECASE)# 2. INSERT IGNORE - UPSERTsqlre.sub(rINSERT\sIGNORE\sINTO,UPSERT INTO,sql,flagsre.IGNORECASE)# 3. REPLACE INTO - UPSERTsqlre.sub(rREPLACE\sINTO,UPSERT INTO,sql,flagsre.IGNORECASE)# 4. GROUP_CONCAT - STRING_AGGsqlre.sub(rGROUP_CONCAT\(([^)])\),rSTRING_AGG(\1, \,\),sql,flagsre.IGNORECASE)# 5. FIND_IN_SET - POSITIONsqlre.sub(rFIND_IN_SET\(([^,]),\s*([^)])\),rPOSITION(\1 IN \2) 0,sql,flagsre.IGNORECASE)# 6. DATEDIFF - 减法sqlre.sub(rDATEDIFF\(([^,]),\s*([^)])\),r\1 - \2,sql,flagsre.IGNORECASE)# 7. DATE_FORMAT - TO_CHARsqlre.sub(rDATE_FORMAT\(([^,]),\s*([^])\),rTO_CHAR(\1, \YYYY-MM-DD\),sql,flagsre.IGNORECASE)# 8. CURDATE - CURRENT_DATEsqlre.sub(rCURDATE\(\),CURRENT_DATE,sql,flagsre.IGNORECASE)# 9. LIMIT offset, count - LIMIT count OFFSET offsetsqlre.sub(rLIMIT\s(\d)\s*,\s*(\d),rLIMIT \2 OFFSET \1,sql,flagsre.IGNORECASE)returnsql# 测试test_sqls[INSERT INTO orders (id, order_no) VALUES (1, ORD001) ON DUPLICATE KEY UPDATE status 1,SELECT * FROM orders LIMIT 20, 10,SELECT GROUP_CONCAT(order_no) FROM orders GROUP BY user_id,SELECT DATEDIFF(2026-08-15, 2026-08-01),]forsqlintest_sqls:print(f原始:{sql})print(f转换:{transform_sql(sql)})print()十二、总结SQL语法兼容性是数据库迁移中不可忽视的环节。通过本文的介绍你应该能够了解常见差异分页、插入更新、字符串函数、日期函数等掌握替换方案使用KaiwuDB的等价语法替换MySQL语法使用自动化工具批量替换SQL语句提高效率测试验证迁移后全面测试SQL语句的执行情况关键要点ON DUPLICATE KEY UPDATE-UPSERTGROUP_CONCAT-STRING_AGGDATEDIFF- 减法DATE_FORMAT-TO_CHARCURDATE-CURRENT_DATELIMIT offset, count-LIMIT count OFFSET offset如果你正在考虑数据库国产化迁移建议提前梳理应用中的SQL语句做好语法兼容性评估。转载自https://blog.csdn.net/u014727709/article/details/163832137欢迎 点赞✍评论⭐收藏欢迎指正