SQLServer 迁移 MySQL:存储过程与 SQL 方言改造实录

SqlServer 数据库存储过程迁移到MySql数据库中遇到的一些问题 由于SqlServer数据库和MySql数据库的存储过程语法较不一样,在迁移存储过程的时候很多细节性问题需要注意,因此记录下来 1、传入参数: ①sqlserver存储过程的传入参数带@符号, 例如: CREATE PROCEDURE [dbo].[Test] @ParmA VARCHAR(50), @ParmB INT ②my... 阅读详情

去年下半年,我们把一个多门店零售的报表系统从 SQLServer 换到了 MySQL。

时间大头不在改 SQL 上,在"数字怎么对不上"上。报错好办,改完就不报了。不报错的那些,得一行行去核。

流水账记一下,顺序大概是:先让能跑,再让算对,最后才管快不快。


一、最开始那半天,报错是成片的

第一轮 SQL 跑下来,报错一片。基本就四类。

GROUP BY 的写法不允许了。 原来 SELECT 里可以带没在 GROUP BY 里的字段,MySQL 严格模式下直接报错。我们改了一批之后发现,有几个报表是故意省写的——分组字段和展示字段本来就一一对应,改起来反而让执行计划变差。最后统一把这项检查关掉了,在代码层做校验。

这个处理不算标准做法,但当时没更好的选择。

TOP 全部改成 LIMIT。 没难度,但量太大,漏一个就跑不过,反复编译反复试。

ISNULL 改成 IFNULL。 这个简单,注意参数顺序别搞反就行。

字符串拼接。 这个不报错,放到下一节说。


二、不报错的才是真坑

DATEDIFF 顺序反了,环比全成负数

报表里有"近 30 天""环比上期",都在用 DATEDIFF 算天数差。

SQLServer 是三个参数,单位放第一位:


MySQL 只有两个参数,没有单位。迁移的时候把单位删了,参数顺序没动,结果全反了,算出来是负数。

报表照常能跑,只是所有时间差都是负的,环比显示成一两百的负增长。

这个错了快一周才发现,因为负增长在报表里太正常了。 没人会盯着一张"本月比上月下降"的表怀疑代码。

后来加了个笨办法:所有日期函数改完,拿一个已知答案的日期手工对一遍。

加号变成加法,标题列全是 0

报表导出要拼标题,原来是这么写的:


到 MySQL,加号就是加法。前面那个字符串转成数字是 0,0 加什么都没了。

结果标题列变成纯数字,或者干脆是 0。一个错都不报。

改成 CONCAT 之后又冒出个小问题:CONCAT 里只要有 NULL,整个结果就是 NULL。原来在 SQLServer 上碰巧没遇到,迁过来发现多了一批空白行,也是查了一阵才反应过来。

时间差 8 小时,日报晚上八点才有数据

上线第二天,运营说今天的数据是空的,晚上八点之后才慢慢出来。

原因不复杂:MySQL 那边的服务器时区设的是 UTC,取当前时间比北京时间晚 8 小时。SQLServer 取的是服务器本地时间,从来没为这个操心过。

连接串和实例两处都改了才正常。

改完还有个后遗症:库里有两种时间类型,一种会跟着时区转,一种不会。改完之后历史数据得重新看一遍,不能只测新写进去的。

翻页翻出重复数据

报表导出按页取,一页五百条。翻到第三页,发现两条和第一页一模一样。

问题不在分页,在排序。排序那个字段重复值太多(同一天几十个门店),相同值之间谁前谁后,数据库不保证。两次执行顺序一变,翻页就会重复或者漏。

解决办法就是把排序字段后面再挂一个唯一的列兜底。这个在 SQLServer 上其实也有,只是当时数据少,没露出来。


三、字段类型,几个不出声的地方

字符串前缀。 SQLServer 里中文串前面习惯带个 N,迁过来这个写法不认,得批量清掉。用正则扫要小心,别把正文里的字母也删了。

时间精度。 原来那边时间是带毫秒的,MySQL 默认只到秒。迁完同一秒里的两条记录时间戳一模一样,按时间排序就乱了,按时间去重还会把两笔合成一笔,报表少算。后来把精度调回去了,顺带发现 ORM 那边也要跟着调。

超长的处理方式变了。 SQLServer 是截断,给个警告但数据进去了。MySQL 严格模式直接报错。导历史数据时一次报了几百条,最后把几个备注字段加长了事。

金额字段。 别顺手把小数位加上去。小数位一多,报表里做除法会有尾差,汇总就对不上。

布尔字段。 底层存的是 0/1,但驱动读出来是布尔还是数字,跟连接配置有关。我们这边出现过前端显示 true/false 的,查了半天是连接串没配。


四、ROW_NUMBER 改写,这段最费劲

报表里最常用的一招是"取每个门店最新的一条"。

SQLServer 一个 ROW_NUMBER 加 PARTITION BY 就完了。目标库有一部分版本不支持这个,得自己想办法。

第一种写法是用户变量。 在 SELECT 里用变量累加行号,按门店分组重置。

能跑,但不稳。新版本里这种写法已经不推荐了,而且优化器不保证 SELECT 里表达式的计算顺序,行号经常乱。老版本上勉强能用,等于留了个升级的雷。

第二种是先把每个门店的最大时间取出来,再关联回去。

看着没毛病,实际出了大问题:同一门店同一秒有两笔的时候,关联会出两条。

表本来几十万行,结果多出来一截,报表总额也偏高了一些。没有报错,就是数字大了一点。

这个查了一天多。一开始怀疑源库有重复数据,去查,没有;怀疑关联条件写错,换了三种写法结果一样;最后把中间结果导出来逐行比,才发现是时间戳相同导致一对多。

最后的解法是拿唯一键代替时间。 取每个门店最大的那条 ID,因为 ID 唯一,不会再出一对多。

前提是"最新的"和"ID 最大的"是同一件事。我们这个场景成立,因为 ID 是递增的。如果业务上有补录,这个改法就不行了,得另外想办法。


五、锁:原来那些写法搬不过来

SQLServer 那套代码里,几乎每个报表查询后面都跟着 NOLOCK。

原因很实际:报表跑起来会卡住业务写入,加了就不卡了,代价是可能读到还没提交的数据。对报表来说这笔交易划算。

迁过来第一件事就是把 NOLOCK 全删了。MySQL 没这个写法,而且它读的时候本来就不加锁、不阻塞写入。

但反过来出了个坑。

有个过程,为了"读的时候数据别被人改",原来写的是带更新锁的查询。我们照着改了,换成了 FOR UPDATE。

结果这个报表一跑,那张门店表像被锁住一样,下单接口大面积超时。

后来才搞明白:MySQL 在某些隔离级别下,范围条件加锁锁的不是命中的那几行,是整个区间。SQLServer 默认级别下没这个行为,所以从来没人注意过。

最后那个 FOR UPDATE 直接删了——报表本来就不需要锁。


六、存储过程,最后决定不迁

三十来个存储过程,平均两百行,最长的一个七百多行。

本来打算一个一个翻译:变量去掉 @、临时表换写法、异常处理换写法、IF 语法调一调。

翻到第五个就发现方向不对。三个原因:

一是 MySQL 的存储过程不好调试,出错只能临时加查询打点,改完自己都不敢确认逻辑对不对;二是嵌套 IF 一多,翻完的代码没人看得懂;三是这套东西后面还要维护。

最后全部拆成 Java。

拆法是按阶段拆,每个阶段落一张中间表:取基础数据 → 算中间指标 → 汇总 → 输出。每步能单独跑,能看中间结果,某个指标算错只改那一步。

代价是事务边界变了。原来一个过程是一个事务,失败全回滚;拆成几步之后,第三步失败,前两步的结果已经写进去了,重跑会重复累加。

处理办法是每张中间表加个批次号,重跑前按批次号先删。当时觉得多余,后来救过两次——上游数据补录要重算几个月的数据,直接按批次重跑,没碰生产数据。


七、多表关联:3 秒变成好几分钟

有个区域汇总报表,五张表关联,三层分组。

SQLServer 上三秒出结果,迁过来第一版跑了好几分钟。

老版本的 MySQL 在关联上的优化比 SQLServer 弱不少,几张表一关联,驱动表选错就是成倍地扫。

三步处理,按效果排:

先把明细聚合,再去关联。 原来是明细表直接和门店、区域、商品表关联,最后才分组。改成先把明细按门店和日期汇总成中间表,再跟维度表关联。参与关联的行数一下就下来了。

补索引。 原来只有单列索引,换成联合索引之后能直接走索引,不用再回表。

把子查询改成关联。 IN (子查询) 这种写法,MySQL 有时候会先把子查询算成临时表再全表扫,SQLServer 一般能处理好。改成 JOIN 之后差别很明显。

最后降到几秒,能接受。


八、其他零碎的

  • UPDATE 带关联的写法不一样,改错顺序会把整表更新掉,而且不报错
  • MERGE 换成 INSERT ... ON DUPLICATE KEY UPDATE
  • 几个字符串函数换了名字,注意有的算字符数、有的算字节数,中文会算错
  • UNION 里的排序和限制,原来的写法要改成每个分支加括号,不然限制作用在整个结果上
  • 排序规则默认值不同,卡号、单号这种查询查不到,八成是这个

sqlserver迁移到mysql实战 公司旧有项目使用sqlserver,会的人少,扩展性也差,还要收费,现在要迁移到mysql。 阅读详情

相关推荐

从 MSSQL 到 MySQL 的数据迁移完全指南

市场上存在众多数据备份工具,它们各自有特点和适用场景。例如:mysqldump:最常用的MySQL备份工具,免费且易于使用。:免费且支持无锁备份的高性能工具。:由Oracle提供的商业备份工具,提供丰富的功能。选择合适的备份工具需要考虑的因素包括备份速度、数据完整性、存储空间、恢复效率和成本等。对于企业环境,通常会考虑商业解决方案以获取更稳定和高效的备份服务。

weixin_42153793的博客 1002

MSSQL迁移MYSQL问题总结

文章目录MSSQL 迁移 MYSQL存储过程及函数写法不同函数存储过程SQL语法不同原生sqlMyBits sql MSSQL 迁移 MYSQL 最近在公司做了mssql迁移到mysql的测试,因为之前存在大量的存储过程,所以对迁移造成了不少的阻力。在此,把遇到的问题做个记录。 存储过程及函数写法不同 函数 功能 mssql函数 mysql函数 添加时间 DATEADD(datep...

谁呀这是? 635

MSSQL转MySQL数据库迁移工具实战指南_MSSQL-to-MySQL

在当今数据驱动的时代,迁移数据库是一项重要的任务,它允许组织将数据从一个平台转移到另一个平台,以提高效率、降低成本或实施新技术。在众多数据库迁移工具中,MSSQL-to-MySQL工具以其简便的操作和高效的迁移过程而受到业界的关注。它设计用于将Microsoft SQL Server (MSSQL)数据库迁移到MySQL数据库平台,为IT专业人员提供了一个可靠的选择来转换其数据资产。

weixin_29717341的博客 942

如何将 sqlserver 数据迁移到 mysql

💎将SQL Server数据迁移到MySQL是一个常见的数据库迁移任务,通常涉及以下几个关键步骤:导出SQL Server数据、转换数据格式为MySQL兼容格式、导入数据到MySQL数据库。下面我将详细解释每个步骤,并提供一些示例代码和工具。将SQL Server数据迁移到MySQL涉及导出数据转换数据格式和导入数据三个关键步骤。你可以根据具体需求选择适合的工具和方法来实现迁移。希望这些信息能帮助你顺利完成数据库迁移任务。

李赛赛的专栏 6434

数据库迁移利器:从MSSQL到MySQL的转换工具指南

自20世纪60年代末关系数据库的诞生以来,数据库管理系统(DBMS)已经走过了漫长的发展道路。起初,数据库系统主要服务于大型企业,主要采用层次和网络数据库模型。随着时间的推移,特别是IBM在1970年代开发出关系数据库模型之后,关系数据库管理系统(RDBMS)逐渐成为主流。RDBMS以其结构化的查询语言(SQL)和高效的数据管理能力,迅速获得了市场的青睐。进入21世纪后,随着互联网的普及和大数据的兴起,数据库管理系统也面临了新的挑战。

weixin_35019679的博客 1093

SAP中寄售结算规则及要点分析

在做MRKO寄售结算时,系统会根据选定的期间和供应商等条件,将符合条件的寄售消耗或寄售上线的物料凭证找出。然后以供应商为单位。合并产生一张会计凭证。下图显示了通过MRKO结算后自动生成的会计凭证。 那么,在MRKO做寄售结算的规则是什么样的?做为寄售业务处理者的物流和财务需要掌握和了解哪些关于寄售结算的规则和控制逻辑。下面以笔者的经验分析一下: 1、寄售物料在系统中有两种处理方法,一种是通过MB1B 411 K ,通常该操作达到两个目的:将物料从仓库转移到线边库(表示即将要投入生产了)的同时将寄售库

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 8297

sqlserver存储过程迁移mysql_【教程】sqlserver数据迁移到mysql数据库的技巧

我们在做项目开发的时候使用的是SQL Server数据库,但是我们要将存储的数据库调整为MySQL又该怎么办呢?那么下面我们就一起去看看把sqlserver数据迁移到mysql数据库的技巧。一、SQL Server中常用数据类型与MySQL不同的地方 二、将SQL Server数据迁移到MySQL需要注意的一些问题1、唯一索引的不同,sql server的唯一索引的字段只能允许存在一个null值,...

weixin_42356552的博客 1703

BitLocker加密盘解密实战:从隐藏分区到密钥恢复的全过程

本文深入探讨了BitLocker加密盘在密钥丢失或遗忘情况下的解密实战方法。文章系统性地介绍了从理解加密机制、制作取证镜像,到深度扫描隐藏分区、分析内存转储寻找密钥残留,最终利用恢复密钥解锁加密卷的全过程。重点剖析了非标准恢复路径,为数据恢复和数字取证工作提供了专业的技术框架和实战思路。

weixin_29268385的博客 336

浅析MySQL数据迁移与恢复:从SQLServer转型到MySQL

作为从SQLServer转向MySQL的运维人员,理解MySQL的数据迁移和恢复机制至关重要。与SQLServer直接附加实体文件和日志文件的方式不同,MySQL采用了不同的数据管理方法。本文将系统介绍MySQL的数据迁移技术、备份恢复策略以及底层存储原理,特别针对Docker+Linux环境下的运维实践。

李赛赛的专栏 1690

Qualcomm平台下基于QSEE的指纹识别方案移植之四TA移植

本文只介绍TA移植的过程,不做技术分析,关于TA开发另做记录。 一、TA介绍 TA,Trusted application 可信应用,是运行于QSEE中的可执行程序。 指纹TA文件如下,形式一般是 xxx.mbn; xxx.b0 ~ xxx.b6, xxx.flist, xxx.mdt; xxx.mbn 可以理解为其它几个文件的集合,签名的时候用的就是这个文件,签完名之后,有对应的工具将它...

梦路遥 7549

【漏洞复现】CVE-2024-44902 Thinkphp反序列化漏洞

Thinkphp v6.1.3至v8.0.4版本中存在反序列化漏洞,攻击者可利用此漏洞执行任意代码。

渗透之路,攻防之间皆学问 6712

MySQL与SQLServer的数据迁移

1.背景介绍 1. 背景介绍 在现代企业中,数据迁移是一个非常重要的任务。随着业务的扩展和发展,企业需要将数据从一个数据库系统迁移到另一个数据库系统。MySQL和SQL Server是两个非常流行的关系型数据库管理系统,因此在实际应用中,数据迁移任务是非常常见的。 在本文中,我们将深入探讨MySQL与SQL Server的数据迁移,涵盖其核心概念、算法原理、最佳实践、实际应用场景和工具推荐等...

AI天才研究院 1163

CloudCompare 二次开发(16)——计算点云最值

不依赖任何第三方点云相关库,使用ClopudCompare计算点云最值。

点云侠的博客 518

从mysql迁移到mssql的弯路

因为自己擅长的是MS SQL Server,加上最近为了整理各个不同数据源到统一的数据库,因此将遇到的坑写下来,方便日后查找。 0x0:坑 这次遇到的坑是从mysql迁移到mssql,以前只是稍微接触过mysql,对mysql迁移到mssql,网上搜索的结果大多数是建立链接服务器,但我建立之后发现虽然可以用,只不过数据量太大,导致查询过程中会整台服务器卡顿,这样使得迁移步骤更加麻烦。再

从入门到放弃 1024

5大步骤!轻松玩转Dorisoy.Rigger:基于.NET Core 6、MAUI和Blazor的多数据库开发框架生成器

各位小伙伴,你们是否厌倦了每次项目启动都要从头配置数据库连接、编写重复的代码?今天,我们就来聊聊如何使用Dorisoy.Rigger这个强大的开发框架生成器,让你的.NET Core 6、MAUI和Blazor项目开发变得简单又高效!准备好迎接开发的新乐趣了吗?让我们一起开始吧!接下来,我们需要定义数据模型。假设我们有一个简单的用户表,包含ID、用户名和密码字段。在项目中创建一个新的类文件,命名为User.csset;set;set;这段代码定义了一个用户模型,其中包含了用户的ID、用户名和密码。

java专栏 1741

SAP Retail 补货里的 Requirement Groups,站点和商品太多时,主数据维护如何做减法

SAP Retail补货主数据设计中,Requirement Groups(需求组)是常被低估但至关重要的分类机制。它通过将具有相同补货需求的接收方(如门店)按商品分类(Merchandise Category)分组,大幅降低主数据维护量。在大型零售场景中(如800家门店、6万商品),直接维护每个门店和商品的组合参数会导致维护量失控。Requirement Groups允许企业按品类特性(如乳制品、饮料等)为不同门店组设置统一补货参数,并随业务变化灵活调整。该机制与商品分类紧密绑定,不同于MRP Group

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 68

sqlserver迁移数据到mysql_如何把sqlserver数据迁移到mysql数据库及需要注意事项

在项目开发中,有时由于项目开始时候使用的数据库是SQL Server,后来把存储的数据库调整为MySQL,所以需要把SQL Server的数据迁移到MySQL。下面是小编日常整理的一种sqlserver数据库迁移的方法。一、SQL Server中常用数据类型与MySQL不同的地方二、将SQL Server数据迁移到MySQL需要注意的一些问题1、唯一索引的不同,sql server的唯一索引的字段...

weixin_35521169的博客 1281

EtherCAT用TwinCAT 3跑DC报0x2C或者0x1A错误码

EtherCAT用TwinCAT 3跑DC报0x2C或者0x1A DC报错 ///////////////////////////////////////////////////////////////////////////////////////// /** \brief Checks communication and synchronisation variables and update AL status / AL status code if an error has occurr

PI_sunyang的博客 5308

mssql 存储过程转mysql_sql Sever的存储过程如何转换为mysql

sql Sever的存储过程如何转换为mysql总体来说,sql sever和Mysql的存储过程的思路都是一样的,但是在语法和结构上还是有很大的区别的。1. 在mysql中写存储过程所有的dbo都要去掉。2. 在sql sever中查询分析器直接用create PROCEDURE就可以,但是在mysql中必须用DELIMITER$$来开头,因为在mysql中认定“;”为结束符号,所以我们必须要改...

weixin_39622150的博客 417

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SQLServer 迁移到 MySQL 工具对比

如果仔细观察,可以发现上图中各个数据库的大小是不一致的,基本的判断是由于各种工具在映射数据表字段时,字段长度取值可能不能而引起的。以上四款软件中,最不推荐使用的是 Navicat Premium,主要原因是数据的完整性表现较差,转换后的数据不能立即用于生产环境,需要程序员仔细自行查找原因和分析。由于程序是基于 O/R mapping 编写,并且数据库中没有使用存储过程、用户函数等数据库功能,因此仅仅需要考虑的是数据库中的数据如何转换到新的 MySQL 数据库中。

2301_76376647的博客 2635

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

SQL方言:传统关系型数据库下的方言对比

SQL语法:记录在各个传统关系型数据库下的SQL方言写法

yxd179的博客 1422

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[MySQL] SqlServer 迁移到 MySQL 方法介绍

一、原则: 只迁移表结构和数据,存储过程、函数、触发器尽量自己改写,并充分测试。 迁移前,先设置好数据库的一些参数,比如默认存储引擎,默认编码等,方便后续导入。 二、方法: 1、使用MySQL Workbench   MySQL Workbench提供了Migration Wizard(数据库迁移)功能,支持MSSQL的数据形式转换为MYSQL下的数据格式;   具体参...

awueu25069的博客 270

如何将sqlserver迁移到mysql_如何将数据库从SQL Server迁移到MySQL

一、迁移Database Schema。首先使用Sybase Powerdesigner的逆向工程功能,逆向出SQL Server数据库的物理模型。具体操作是在Powerdesigner中选择“File”,“Reverse Engine”再选择Database,将DBMS选择为SQL Server,如图:然后选择数据源,也就是要具体连接到的SQL Server数据库服务器,然后选择要逆向的数据库名...

weixin_35224206的博客 791

SQL Server 数据库迁移到 MySQL 的完整指南

将 SQL Server 数据库迁移到 MySQL 是一个复杂的过程,涉及多个步骤和注意事项。通过合理的规划和工具的使用,可以大大降低迁移的难度和风险。希望本文能够帮助你顺利完成数据库迁移,并在新的环境中获得更好的性能和成本效益。??如果你在迁移过程中遇到任何问题,欢迎在评论区留言,我会尽力为你解答。

2611_94925926的博客 578
上一篇: docker 拉取镜像失败。报Error response from daemon
learnjava1989
博客等级 码龄9年 9粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值