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

相关推荐
五阿哥永琪29 分钟前
MySQL 慢查询定位与 SQL 性能优化实战指南
sql·mysql·性能优化
C++业余爱好者1 小时前
SQL语言家族入门指南:标准SQL、T-SQL与PL/SQL详解
数据库·sql
白衣衬衫 两袖清风2 小时前
ABP框架+Dapper执行原生sql
sql·c#·.net
小程故事多_802 小时前
开源界核弹级输出!蚂蚁 Agentar-Scale-SQL 凭 “编排式扩展” 技术,成为 Text-to-SQL 天花板
数据库·人工智能·sql·开源·aigc·embedding
xiaok4 小时前
GROUP BY进阶用法
mysql
李慕婉学姐4 小时前
【开题答辩过程】以《基于Android的健康助手APP的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
android·java·mysql
qq_12498707534 小时前
基于springboot健康养老APP的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·mysql·微信小程序·毕业设计
亚林瓜子5 小时前
mysql命令行手动导入csv数据到指定表
数据库·mysql·gui·csv·cli·db·import
一分半心动5 小时前
lnmp架构 mysql数据库Cannot assign requested address报错解决
linux·mysql·php
ChristXlx5 小时前
Linux安装mysql(虚拟机适用)
linux·mysql