统一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

相关推荐
川石课堂软件测试几秒前
Python | 高阶函数基本应用及Decorator装饰器
android·开发语言·数据库·python·功能测试·mysql·单元测试
奇点 ♡3 小时前
MySQL基础题
数据库·sql·mysql
cherry52303 小时前
Java大厂面试真题:Spring Boot + 微服务 + 缓存架构三轮技术拷问实录
jvm·spring boot·mysql·微服务·java面试·分布式架构·redis缓存
唐古乌梁海3 小时前
【mysql】MySQL 数据库迁移
数据库·mysql·adb
啊吧怪不啊吧3 小时前
SQL之表的时间类内置函数详解
大数据·服务器·数据库·sql
JanelSirry3 小时前
真实场景:防止缓存穿透 —— 使用 Redisson 布隆过滤器
数据库·mysql·缓存·redisson·布隆过滤器
神色自若3 小时前
abpVnext 获取token报错,配置文件从sqlerver切换到oracle,再切换回来sqlerver无法获取token
oracle·sqlserver·abpvnext
mmm.c3 小时前
mysql启动提示1067:进程意外终止
数据库·mysql
虎子_layor4 小时前
PostgreSQL这么多优势,为什么还要使用MySQL
后端·sql
Hello.Reader4 小时前
Flink 流式计算的状态之道从 Table/SQL 语义到算子状态与 TTL 精准控制
sql·flink·linq