统一SQL-支持Oracle decode函数到TDSQL-MySQL的转换

统一SQL介绍

https://www.light-pg.com/docs/LTSQL/current/index.html

源和目标

数据库:Oracle

目标数据库:TDSQL-MySQL

操作目标

在Oracle中,decode函数语法如下图:该函数功能是将 expr与每个 search 依次做比较,并返回对比结果。

  • 如果expr和search匹配,则返回result
  • 如果expr没有找到匹配项,则返回default,如果default被省略,则返回null

在TDSQL-MySQL没有与之对应的函数,由此为适配该功能,统一SQL对包含decode函数的SQL语句使用TDSQL-MySQL的其他特性进行改写,使改写后的语句在TDSQL-MySQL中运行时表现相同的功能。

统一SQL转换

改写方案

统一SQL使用TDSQL-MySQL中的case...when...特性来替换decode函数。

转换案例

复制代码
-- 转换前Oracle SQL
SELECT 
 DECODE(SIGN((5*3-2)-(3*4-1)),0,'相等',1,'(5*3-2)大','(3*4-1)大') AS c1,
 DECODE(INSTR('CLARK','S'), 0, '不含有 S', '含有 S') AS "CLARK",
 DECODE(INSTR('KING','S'), 0, '不含有 S', '含有 S') AS "KING",
 DECODE(INSTR('MILLER','S'), 0, '不含有 S', '含有 S') AS "MILLER",
 DECODE(INSTR('ADAMS','S'), 0, '不含有 S', '含有 S') AS "ADAMS",
 DECODE(INSTR('FORD','S'), 0, '不含有 S', '含有 S') AS "FORD",
 DECODE(INSTR('JONES','S'), 0, '不含有 S', '含有 S') AS "JONES"
FROM DUAL;
C1      |CLARK|KING |MILLER|ADAMS|FORD |JONES|
--------+-----+-----+------+-----+-----+-----+
(5*3-2)大|不含有 S|不含有 S|不含有 S |含有 S |不含有 S|含有 S |

-- 转换后TDSQL-MySQL SQL
select
	case
		when SIGN((5 * 3-2)-(3 * 4-1))= 0 then '相等'
		when SIGN((5 * 3-2)-(3 * 4-1))= 1 then '(5*3-2)大'
		else '(3*4-1)大'
	end as `c1`,
	case
		when instr('CLARK', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `CLARK`,
	case
		when instr('KING', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `KING`,
	case
		when instr('MILLER', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `MILLER`,
	case
		when instr('ADAMS', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `ADAMS`,
	case
		when instr('FORD', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `FORD`,
	case
		when instr('JONES', if(binary 'S' = '', null, binary 'S'))= 0 then '不含有 S'
		else '含有 S'
	end as `JONES`
from DUAL
c1      |CLARK|KING |MILLER|ADAMS|FORD |JONES|
--------+-----+-----+------+-----+-----+-----+
(5*3-2)大|不含有 S|不含有 S|不含有 S |含有 S |不含有 S|含有 S |



-- 准备测试数据,以下是Oracle语句,对应的TDSQL-MySQL准备语句也可以通过统一SQL进行转换后在目标库执行
DROP TABLE unisql_decode_test;
CREATE TABLE unisql_decode_test(id int, name varchar(10));
INSERT INTO unisql_decode_test(id,name) values(1,'Linda');
INSERT INTO unisql_decode_test(id,name) values(2,'Tom');
INSERT INTO unisql_decode_test(id,name) values(3,'Richar');
INSERT INTO unisql_decode_test(id,name) values(4,'Nancy');
INSERT INTO unisql_decode_test(id,name) values(5,'Jane');
INSERT INTO unisql_decode_test(id,name) values(6,'Kiko');

-- 转换前Oracle SQL 有默认值的情况
SELECT 
	id,
	name,
	decode(id,
			 1,'Southlake', 
             2, 'San Francisco', 
             3, 'New Jersey', 
             4, 'Seattle',
                'Non domestic') AS domestic
FROM unisql_decode_test;
ID|NAME  |DOMESTIC     |
--+------+-------------+
 1|Linda |Southlake    |
 2|Tom   |San Francisco|
 3|Richar|New Jersey   |
 4|Nancy |Seattle      |
 5|Jane  |Non domestic |
 6|Kiko  |Non domestic |

-- 转换后TDSQL-MySQL 
select
	`id`,
	`name`,
	case
		when `id` = 1 then 'Southlake'
		when `id` = 2 then 'San Francisco'
		when `id` = 3 then 'New Jersey'
		when `id` = 4 then 'Seattle'
		else 'Non domestic'
	end as `domestic`
from `unisql_decode_test`
id|name  |domestic     |
--+------+-------------+
 1|Linda |Southlake    |
 2|Tom   |San Francisco|
 3|Richar|New Jersey   |
 4|Nancy |Seattle      |
 5|Jane  |Non domestic |
 6|Kiko  |Non domestic |


-- 转换前Oracle SQL 没有默认值的情况
SELECT 
	id,
	name,
	decode(id,
			 1,'Southlake', 
             2, 'San Francisco', 
             3, 'New Jersey', 
             4, 'Seattle') AS domestic
FROM unisql_decode_test;
ID|NAME  |DOMESTIC     |
--+------+-------------+
 1|Linda |Southlake    |
 2|Tom   |San Francisco|
 3|Richar|New Jersey   |
 4|Nancy |Seattle      |
 5|Jane  |             |
 6|Kiko  |             |

-- 转换后TDSQL-MySQL 
select
	`id`,
	`name`,
	case
		when `id` = 1 then 'Southlake'
		when `id` = 2 then 'San Francisco'
		when `id` = 3 then 'New Jersey'
		when `id` = 4 then 'Seattle'
	end as `domestic`
from
	`unisql_decode_test`
id|name  |domestic     |
--+------+-------------+
 1|Linda |Southlake    |
 2|Tom   |San Francisco|
 3|Richar|New Jersey   |
 4|Nancy |Seattle      |
 5|Jane  |             |
 6|Kiko  |             |

Oracle其他函数到TDSQL-MySQL的转换可参考统一SQL官方手册

https://www.light-pg.com/docs/LTSQL/current/develop/Oracle2TDSQL-MySQL/index.html

相关推荐
瀚高PG实验室6 小时前
通过数据库日志获取数据库中的慢SQL
数据库·sql·瀚高数据库
invicinble6 小时前
对于Mysql深入理解
数据库·mysql
阳光九叶草LXGZXJ7 小时前
达梦数据库-学习-47-DmDrs控制台命令(LSN、启停、装载)
linux·运维·数据库·sql·学习
霖霖总总8 小时前
[小技巧56]深入理解 MySQL 聚簇索引与非聚簇索引:原理、差异与实践
数据库·mysql
伐尘8 小时前
【MySQL】间隙锁 与 排他锁 的区别
数据库·mysql
快乐非自愿10 小时前
【面试题】MySQL 的索引类型有哪些?
数据库·mysql·面试
霖霖总总11 小时前
[小技巧55]深入解析数据库日志机制:逻辑日志、物理日志与物理逻辑日志在 MySQL InnoDB 中的实现
数据库·mysql
ruxshui12 小时前
Python多线程环境下连接对象的线程安全管理规范
开发语言·数据库·python·sql
Mr_Xuhhh13 小时前
MySQL数据表操作全解析:从创建到管理
数据库·sql·oracle
大模型玩家七七13 小时前
向量数据库实战:从“看起来能用”到“真的能用”,中间隔着一堆坑
数据库·人工智能·python·深度学习·ai·oracle