统一SQL支持解析和改写Oracle字符串拼接符

统一SQL支持解析和改写Oracle字符串串联运算符

【统一sql】:https://www.light-pg.com/docs/LTSQL/current/index.html

LightDB 统一SQL 是一款基于 Go 开发的 SQL 转换中间件,支持将 Oracle 常用 SQL 语法翻译转换为其他数据库的 SQL 。以主流数据库Oracle的SQL为基准,将SQL语句转换为其他信创数据库(LightDB、PostgreSQL、TDSQL、DM8、OceanBase、openGauss等)的SQL语句。目标是降低业务部门适配信创数据库的成本,让用户尽可能少地修改数据访问层代码,使基于Hibernate、JPA、MyBatis等框架的Java应用程序,基于oci、libmysqlclient、cres开发工具、hsdb的c/c++应用程序以及其它能够调用c函数的程序都能够直接切换到目标信创数据库,实现信创数据库之间的平滑迁移。

前言

串联运算符 || 用于连接字符串和 CLOB 数据类型的数据。使用串联运算符连接两个字符串后会得到另一个字符串。

Oracle中SQL操作符的优先级如下:

操作符优先级
+, - (正负符号), PRIOR, CONNECT_BY_ROOT, COLLATE1
*, /2
+, - (加减法),3
=, !=, <, >, <=, >=4
IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT] IN, EXISTS, IS OF type5
NOT6
AND7
OR8

可以看出来串联运算符 || 和+, - (加减法),在同一优先级,所有要特别注意。在这里我们称Oracle为源库,转化的库为目标库。

Oracle2PostgreSQL ,Oracle2TDSQL-MySQL5.7

转化语法

目标端是PostgreSQL,TDSQL-MySQL5.7,将||转为concat函数

结果

通过统一sql转化之后的结果:

-- 转换前Oracle SQL:
select '成交价格高于前一日收盘价;成交价格:' || 2 * 1000.00 || '元,收盘价:' || null || '' || '   '|| 'end'|| ''  FROM DUAL;
'成交价格高于前一日收盘价;成交价格:'||2*1000.00||'元,收盘价:'||NULL||''||''||'END'||''|
------------------------------------------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end                                |

-- 转换后PostgreSQL/TDSQL-MySQL5.7:
SELECT concat(concat(concat(concat(concat(concat(concat('成交价格高于前一日收盘价;成交价格:', 2*1000.00), '元,收盘价:'), NULL), ''), '   '), 'end'), '');
concat                               |
-------------------------------------+
成交价格高于前一日收盘价;成交价格:2000.00元,收盘价:   end|

Oracle2LightDB-Oracle ,Oracle2DM,Oracle2OceanBase-Oracle

转化语法

目标端是LightDB-Oracle,DM,OceanBase-Oracle,,将||转为||

结果

通过统一sql转化之后的结果:

-- 转换前Oracle SQL:
select '成交价格高于前一日收盘价;成交价格:' || 2 * 1000.00 || '元,收盘价:' || null || '' || '   '|| 'end'|| ''  FROM DUAL;
'成交价格高于前一日收盘价;成交价格:'||2*1000.00||'元,收盘价:'||NULL||''||''||'END'||''|
------------------------------------------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end                                |

-- 转换后LightDB-Oracle SQL:
SELECT ((((((('成交价格高于前一日收盘价;成交价格:'||2*1000.00)||'元,收盘价:')||NULL)||'')||'   ')||'end')||'') FROM DUAL;
?column?                          |
----------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end|

-- 转换后达梦 SQL/OceanBase-Oracle SQL:
SELECT '成交价格高于前一日收盘价;成交价格:'||2*1000.00||'元,收盘价:'||NULL||''||'   '||'end'||'' FROM DUAL;
?column?                          |
----------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end|


-- 转换前Oracle SQL:
select 1||2-3||2+1 from dual
1||2-3||2+1|
-----------+
         93|
 
-- 转换后LightDB-Oracle SQL:
SELECT ((1||2)-3||2)+1 FROM dual
?column?|
--------+
      93|

-- 转换后达梦 SQL:
select 1||2-3||2+1 from dual
1||2-3||2+1|
-----------+
1-13       |
  
-- 转换后OceanBase-Oracle:
select 1||2-3||2+1 from dual
1||2-3||2+1|
-----------+
         93|
  

总结

  • 目标库、源库串联运算符优先级不同,源库中串联运算符和加法、减法在同一级,而目标库DM、LightDB-Oracle中串联运算符和加法、减法不在同一级。所以DM中串联的字符串中含有加法或减法,两边数据库结果可能不一致,统一SQL中对LightDB-Oracle中进行括号优先级的处理。

  • 方案中串联运算符会转化成concat函数的那种情况,转化的结果是字符串,字符串在源库和目标库的隐式转化范围不同,这个也需要注意

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值