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

相关推荐
哈里谢顿6 小时前
记录一次sql优化记录
mysql
数据大魔方6 小时前
【期货量化实战】日内动量策略:顺势而为的短线交易法(Python源码)
开发语言·数据库·python·mysql·算法·github·程序员创富
Chasing Aurora6 小时前
数据库连接+查询优化
数据库·sql·mysql·prompt·约束
渐暖°7 小时前
JDBC直连ORACLE进行查询
数据库·oracle
萧曵 丶8 小时前
Next-Key Lock、记录锁、间隙锁浅谈
数据库·sql·mysql·mvcc·可重复读·幻读
zgl_200537799 小时前
ZGLanguage 解析SQL数据血缘 之 标识提取SQL语句中的目标表
java·大数据·数据库·数据仓库·hadoop·sql·源代码管理
莳花微语9 小时前
记录一次OGG进程abended,报错OGG-01431、OGG-01003、OGG-01151、OGG-01296问题的处理
数据库·sql·mysql
尋有緣9 小时前
力扣1355-活动参与者
大数据·数据库·leetcode·oracle·数据库开发
萧曵 丶9 小时前
MySQL三大日志系统浅谈
数据库·sql·mysql
木风小助理11 小时前
三大删除命令:MySQL 核心用法解析
数据库·oracle