SQL 转换有时被描述为将一个数据库函数替换为另一个函数。实际的迁移工作要复杂得多。
两个函数可能名称相似,但行为仍然不同。两个数据库可能接受相似的语法,但处理 NULL 值、日期、数字或文本的方式可能不同。
有用的转换流程必须考虑这些行为,而不仅仅是查询的外观。
分页是一个简单的例子
PostgreSQL 和 MySQL 通常使用以下方式限制结果:
SELECT *
FROM customers
LIMIT 10;
SQL Server 可以使用以下方式表达相同的基本请求:
SELECT TOP 10 *
FROM customers;
关键字的变化很容易处理。当分页还包括排序、偏移量或并列结果时,周围的查询就变得更加重要。
日期运算需要上下文
MySQL 可以使用以下方式增加七天:
SELECT DATE_ADD(order_date, INTERVAL 7 DAY)
FROM orders;
PostgreSQL 可以使用:
SELECT order_date + INTERVAL '7 days'
FROM orders;
语法不同,但迁移还需要考虑数据类型、时区、月份边界,以及日期与时间戳之间的差异。
NULL 值可能改变结果
NULL 行为会影响比较、字符串连接、条件表达式和聚合函数。
转换后的表达式在目标数据库中可能有效,但当某个输入为 NULL 时,返回的结果可能不同。因此,警告信息和具有代表性的测试数据非常重要。
数据类型不是可以互换的标签
源数据库使用的类型可能在目标数据库中没有完全对应的类型。
转换必须考虑:
• 最大长度
• 数值精度和小数位数
• 时区支持
• Unicode 行为
• 布尔值表示方式
• JSON 存储
• 二进制数据
如果某种类型会改变可存储的值,仅仅选择名称相似的类型是不够的。
标识符和引用方式也有所不同
SQL Server 通常使用方括号包围标识符。MySQL 通常使用反引号。PostgreSQL 和其他系统会在特定情况下使用双引号。
引用规则会与大小写、保留字和架构名称相互影响。转换后的标识符应结合目标数据库的上下文进行检查。
过程化 SQL 需要特别关注
存储过程、变量、异常处理、临时对象和动态 SQL 通常包含最具数据库特定性的行为。
这些结构可能需要重新组织,而不是直接替换。转换器可以提供初步转换和诊断,但开发人员应审查最终设计。
支持方言感知的转换应做到什么
结构化 SQL 转换器应:
• 明确源方言和目标方言
• 应用一致的转换规则
• 保留易读的结构
• 标示不确定或对行为敏感的映射
• 避免掩盖人工审查的必要性
目标不是承诺一次点击即可完成完美迁移。
目标是减少重复改写,使重要差异清晰可见,并为开发人员提供更可靠的测试起点。
SQL 方言共享基础,但其行为并不完全相同。优秀的转换会同时尊重这两方面的现实。