转MySQL遇到的语法差异及解决方案
最近公司项目需要从SQL Server转到MySQL, 在转的过程中遇到两者语法之间的一些差异,在网上找了解决方案后,特记录在此。由于解决方案可能有很多种,我只记录了自己使用过的,仅作参考。
1. 拼接字符串
使用
group_concat
方法
-
MSSQL
( SELECT LEFT(dal.DeliveryAreaList, LEN(dal.DeliveryAreaList) - 1) FROM ( SELECT ( SELECT CAST(DeliveryArea AS VARCHAR) + '|' FROM Rel_MainCommodityDeliveryArea WHERE MainCommodityId = a.MainCommodityId AND DeliveryArea <> 0 AND Disabled = 0 ORDER BY DeliveryArea ASC FOR XML PATH('') ) AS DeliveryAreaList ) dal ) AS DeliveryAreasList
-
MySQL
(select group_concat(rmcda.DeliveryArea order by rmcda.DeliveryArea desc separator '|') from Rel_MainCommodityDeliveryArea rmcda where rmcda.MainCommodityId = a.MainCommodityId and rmcda.DeliveryArea <> 0 and rmcda.Disabled = 0) as DeliveryAreasList
2. MySQL中和update set select语法
MySQL中
update set select
无from
,需要使用更新多表的语法
-
MSSQL
update fc set fc.UseScenarios = (ISNULL(fc.InheritName, '') + ISNULL(fmc.MainCommodityName_Postfix, '') + '-' + ISNULL(cn.ChannelAlias, '') + ISNULL(fc.CommodityName_Postfix, '')), fc.UseScenariosEn = (ISNULL(fc.CommodityName_Prefix, '') + ISNULL(fc.InheritName, '') + ISNULL(fmc.MainCommodityName_Postfix, '') + ISNULL(fc.CommodityName_Postfix, '')), fc.[Rec_ModifyBy] = '{updateUser}', fc.[Rec_ModifyTime] = now(3) from Fct_Commodity as fc inner join Fct_MainCommodity as fmc on fc.MainCommodityId = fmc.MainCommodityId inner join Dim_Channel as cn on fc.ChannelId = cn.ChannelId where fc.Disabled = 0 and fmc.Disabled = 0 and fc.InheritName is not null and fc.InheritName <> '' and fmc.[MainCommodityCode] in ({codeList})
-
MySQL
update Fct_Commodity fc, Fct_MainCommodity fmc, Dim_Channel cn set fc.UseScenarios = (ifnull(fc.InheritName, '') + ifnull(fmc.MainCommodityName_Postfix, '') + '-' + ifnull(cn.ChannelAlias, '') + ifnull(fc.CommodityName_Postfix, '')), fc.UseScenariosEn = (ifnull(fc.CommodityName_Prefix, '') + ifnull(fc.InheritName, '') + ifnull(fmc.MainCommodityName_Postfix, '') + ifnull(fc.CommodityName_Postfix, '')), fc.Rec_ModifyBy = '{updateUser}', fc.Rec_ModifyTime = now(3) where fc.MainCommodityId = fmc.MainCommodityId and fc.ChannelId = cn.ChannelId and fc.Disabled = 0 and fmc.Disabled = 0 and fc.InheritName is not null and fc.InheritName <> '' and fmc.MainCommodityCode in ({codeList})
3. MySQL子查询中使用limit
MySQL中子某些子查询不允许
limit
, 如需要使用,需要用select
再包一层
-
MSSQL
SELECT UnitId,UnitName FROM Dim_Unit WHERE UnitName IN ( SELECT TOP 6 fmc.Unit FROM Fct_MainCommodity fmc INNER JOIN Dim_Unit du ON fmc.Unit=du.UnitName WHERE fmc.Disabled=0 AND du.Disabled=0 GROUP BY fmc.Unit ORDER BY COUNT(fmc.Unit) DESC )
-
MySQL
select UnitId, UnitName from Dim_Unit where UnitName in ( select temp.Unit from (select fmc.Unit from Fct_MainCommodity fmc inner join Dim_Unit du on fmc.Unit = du.UnitName where fmc.Disabled = 0 and du.Disabled = 0 group by fmc.Unit order by COUNT(fmc.Unit) desc limit 6) temp)
4. Parameter '@Rec_CreateTime' must be defined
参数化拼sql, 不要用
now(3)
, 直接在代码里面获取当前时间
-
MSSQL
public static Hashtable CreateByCheck(Hashtable htValue,string userID) { if (!htValue.Contains("Rec_CreateTime")) { htValue.Add("Rec_CreateTime", "now(3)"); } if (!htValue.Contains("Rec_CreateBy")) { htValue.Add("Rec_CreateBy", HttpContext.Current == null ? "admin" : userID); } return htValue; }
-
MySQL
public static Hashtable CreateByCheck(Hashtable htValue,string userID) { if (!htValue.Contains("Rec_CreateTime")) { htValue.Add("Rec_CreateTime", DateTime.Now); } if (!htValue.Contains("Rec_CreateBy")) { htValue.Add("Rec_CreateBy", HttpContext.Current == null ? "admin" : userID); } return htValue; }
5 拼接字符串+字符集
(MainCommodityName + ifnull(MainCommodityName_Postfix, ''))
拼接得不到想要的结果[HY000][1267] Illegal mix of collations (utf8_bin,NONE) and (utf8_general_ci,COERCIBLE) for operation '=': 需要加
collate utf8_general_ci
统一字符集
-
MSSQL
select MainCommodityName from Fct_MainCommodity where (MainCommodityName + ifnull(MainCommodityName_Postfix, '')) = '附件上传原料A进A出1003' and Disabled = 0 and ifnull(IsAutoHide, 0) != 1 and MainCommodityId != '27135417-a42b-453f-a1cc-1617d6fc471e';
-
MySQL
select MainCommodityName from Fct_MainCommodity where CONCAT(MainCommodityName, cast(ifnull(MainCommodityName_Postfix, '') as nchar(50))) collate utf8_general_ci = '附件上传原料A进A出1003' and Disabled = 0 and ifnull(IsAutoHide, 0) != 1 and MainCommodityId != '27135417-a42b-453f-a1cc-1617d6fc471e';
6 SQL中使用正则
MSSQL中LIKE后面可以使用正则,但是MYSQL需要使用REGEXP
- MSSQL
select isnull( MAX(BrandCode),99999)+1 as BrandCode from Fct_Brand
where BrandCode like '[0-9][0-9][0-9][0-9][0-9][0-9]'
- MySQL
select ifnull( MAX(BrandCode),99999)+1 as BrandCode from Fct_Brand
where BrandCode regexp '[0-9][0-9][0-9][0-9][0-9][0-9]'