《卸甲笔记》-PostgreSQL和Oracle的SQL差异分析之五:函数的差异(五)

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介:

PostgreSQL是世界上功能最强大的开源数据库,在国内得到了越来越多机构和开发者的青睐和应用。随着PostgreSQL的应用越来越广泛,Oracle向PostgreSQL数据库的数据迁移需求也越来越多。数据库之间数据迁移的时候,首先是迁移数据,然后就是SQL、存储过程、序列等程序中不同的数据库中数据的使用方式的转换。下面根据自己的理解和测试,写了一些SQL以及数据库对象转换方面的文章,不足之处,尚请多多指教。

1、regexp_replace

regexp_replace是使用正则表达式进行替换的函数。源字符串里面符合正则表达式的,替换成目标字符串。Oracle和PostgreSQL都支持regexp_replace,但是参数有些不同。

Oracle的regexp_replace共有六个参数。分别表示源字符串,正则表达式,目标字符串,开始位置(默认为1),替换第几个匹配(默认全部)和一个flg值('i':大小写不敏感 ‘c’:大小写敏感 'n':点号,不匹配换行符号 'm‘:多行模式 'x':扩展模式,忽略正则表达式中的空白字符)。

PostgreSQL中的regexp_replace只有四个参数,分别表示源字符串,正则表达式,目标字符串,替换规则(默认只替换第一个。当替换规则为'g'的时候代表全部替换)。

PostgreSQL中的regexp_replace的功能没有Oracle的regexp_replace的功能强。有些比较复杂的替换,只能自己通过函数实现。

Oracle regexp_replace

SQL> select regexp_replace('abc123xyz888', '[0-9]+') from  dual;

REGEXP
------
abcxyz

SQL> select regexp_replace('abc123xyz888', '[0-9]+', 'ZZZ') from  dual;

REGEXP_REPLA
------------
abcZZZxyzZZZ

SQL> select regexp_replace('abc123xyz888', '[0-9]+', 'ZZZ', 8) from  dual;

REGEXP_REPLA
------------
abc123xyzZZZ

SQL> select regexp_replace('abc123xyz888', '[0-9]+', 'ZZZ', 1, 2) from  dual;

REGEXP_REPLA
------------
abc123xyzZZZ

SQL> select regexp_replace('abc123xyz888', '[a-c]+', 'ZZZ', 1, 1, 'i')  from  dual;

REGEXP_REPLA
------------
ZZZ123xyz888

SQL> select regexp_replace('abc123xyz888', '[A-C]+', 'ZZZ', 1, 1, 'i')  from  dual;

REGEXP_REPLA
------------
ZZZ123xyz888

SQL> select regexp_replace('abc123xyz888', '[A-C]+', 'ZZZ', 1, 1, 'c')  from  dual;

REGEXP_REPLA
------------
abc123xyz888

PostgreSQL regexp_replace

postgres=# select regexp_replace('abc123xyz888', '[0-9]+') ;
错误:  函数 regexp_replace(unknown, unknown) 不存在
第1行select regexp_replace('abc123xyz888', '[0-9]+') ;
            ^
提示:  没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换.
postgres=#  select regexp_replace('abc123xyz888', '[0-9]+', 'ZZZ');
 regexp_replace
----------------
 abcZZZxyz888
(1 行记录)

postgres=#  select regexp_replace('abc123xyz888', '[0-9]+', 'ZZZ', 'g');
 regexp_replace
----------------
 abcZZZxyzZZZ
(1 行记录)

2、regexp_substr

regexp_substr是Oracle的使用正则表达式进行字符串截取的函数。PostgreSQL中的substring函数中可以实现它的简单功能,但是没有Oracle的功能强。如果需要实现它的复杂功能,需要自己使用函数实现。
Oracle的regexp_substr函数有五个参数。分别表示源字符串,正则表达式,开始位置(默认为1),截取第几个匹配(默认第一个)和一个flg值('i':大小写不敏感 ‘c’:大小写敏感 'n':点号,不匹配换行符号 'm‘:多行模式 'x':扩展模式,忽略正则表达式中的空白字符)。
PostgreSQL中的regexp_substr只有三个参数,分别表示源字符串,正则表达式,逃匿符。

Oracle regexp_substr

SQL> select regexp_substr('abc123abc888', '[a-c]+')  from  dual;

REG
---
abc

SQL> select regexp_substr('abc123abc888', '[a-c]+', 2)  from  dual;

RE
--
bc

SQL> select regexp_substr('abc123abc888', '[a-c]+', 5)  from  dual;

REG
---
abc

SQL> select regexp_substr('abc123abc888', '[a-c]+', 1, 2)  from  dual;

REG
---
abc

SQL> select regexp_substr('abc123abc888', '[A-C]+', 1, 1)  from  dual;

R
-

SQL> select regexp_substr('abc123abc888', '[A-C]+', 1, 1, 'i')  from  dual;

REG
---
abc

SQL> select regexp_substr('abc123abc888', '[A-C]+', 1, 1, 'c')  from  dual;

R
-

PostgreSQL substring

postgres=# select substring('abc123abc888', '[a-c]+') ;
 substring
-----------
 abc
(1 行记录)

postgres=# select substring('abc123abc888' from  '[a-c]+') ;
 substring
-----------
 abc
(1 行记录)

postgres=# select substring('Thomas' , '%#"o_a#"%' ,'#');
 substring
-----------
 oma
(1 行记录)

postgres=# select substring('Thomas' from '%#"o_a#"%' for '#');
 substring
-----------
 oma
(1 行记录)

3、regexp_instr

regexp_instr是Oracle的一个搜索字符串中符合表达式的字串位置的一个函数。在PostgreSQL中没有对应的函数,需要自己写函数实现它。
最简单的功能,可以使用position函数和substring函数来模拟实现。

Oracle regexp_instr

SQL> select regexp_instr('abc123abc156', '[1-2]+')  from  dual;

REGEXP_INSTR('ABC123ABC156','[1-2]+')
-------------------------------------
                                    4

SQL> select regexp_instr('abc123abc156', '[1-2]+', 7)  from  dual;

REGEXP_INSTR('ABC123ABC156','[1-2]+',7)
---------------------------------------
                                     10

SQL> select regexp_instr('abc123abc156', '[1-2]+', 1, 2)  from  dual;

REGEXP_INSTR('ABC123ABC156','[1-2]+',1,2)
-----------------------------------------
                                       10

SQL> select regexp_instr('abc123abc156', '[1-2]+', 1, 1, 0)  from  dual;

REGEXP_INSTR('ABC123ABC156','[1-2]+',1,1,0)
-------------------------------------------
                                          4

SQL> select regexp_instr('abc123abc156', '[1-2]+', 1, 1, 1)  from  dual;

REGEXP_INSTR('ABC123ABC156','[1-2]+',1,1,1)
-------------------------------------------
                                          6

SQL> select regexp_instr('abc123abc156', '[A-C]+', 1, 2, 0, 'i')  from  dual;

REGEXP_INSTR('ABC123ABC156','[A-C]+',1,2,0,'I')
-----------------------------------------------
                                              7

SQL> select regexp_instr('abc123abc156', '[A-C]+', 1, 2, 0, 'c')  from  dual;

REGEXP_INSTR('ABC123ABC156','[A-C]+',1,2,0,'C')
-----------------------------------------------
                                              0

PostgreSQL position substring

postgres=# select position(substring('abc123abc156' from '[1-2]+') in 'abc123abc156');
 position
----------
        4
(1 行记录)


postgres=# select 7 - 1 + position(substring(substring('abc123AC158',7) from '[1-2]+') in 'abc123AC158');
 ?column?
----------
       10
(1 行记录)

4、regexp_like

regexp_like是Oracle的一个检索正则表达式条件的一个函数,只能用在条件判断部分。在PostgreSQL中没有对应的函数,需要自己写函数实现它。
最简单的功能,可以简单的使用substring和length函数来模拟。

Oracle regexp_like

SQL> select * from o_test;

        ID NAME       AGE
---------- ---------- ----------
         1 James1234  20
         2 De Haan    20
         2 Greenberg  20
         2 TomLiu     20

SQL> select * from o_test where regexp_like(name, '([aeiou])\1');

        ID NAME       AGE
---------- ---------- ----------
         2 De Haan    20
         2 Greenberg  20

SQL> select * from o_test where regexp_like(name, '([AEIOU])\1');

未选定行

SQL> select * from o_test where regexp_like(name, '([AEIOU])\1', 'i');

        ID NAME       AGE
---------- ---------- ----------
         2 De Haan    20
         2 Greenberg  20

SQL> select * from o_test where regexp_like(name, '([AEIOU])\1', 'c');

未选定行

PostgreSQL length substring

postgres=# select * from p_test where length(substring(name, '([aeiou])\1')) > 0;
 id |   name    | age
----+-----------+-----
  2 | De Haan   | 20
  3 | Greenberg | 20
(2 行记录)

postgres=# select * from p_test where length(substring(name, '([AEIOU])\1')) > 0;
 id | name | age
----+------+-----
(0 行记录)

postgres=# select * from p_test where length(substring(name, '([AEIOUaeiou])\1')) > 0;
 id |   name    | age
----+-----------+-----
  2 | De Haan   | 20
  3 | Greenberg | 20
(2 行记录)

参考文档:

PostgreSQL 9.4.4 中文手册:
http://www.postgres.cn/docs/9.4/functions-string.html (字符串函数和操作符)
Database SQL Language Reference:
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions148.htm#SQLRF06300
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions149.htm#SQLRF06302
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions150.htm#SQLRF06303
http://docs.oracle.com/cd/E11882_01/server.112/e41084/conditions007.htm#SQLRF00501

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
5月前
|
SQL JSON 数据格式
SPL 处理多层 JSON 数据比 DuckDB 方便多了
esProc SPL 处理多层 JSON 数据比 DuckDB 更便捷,尤其在保留 JSON 层次与复杂计算时优势明显。DuckDB 虽能通过 `read_json_auto()` 将 JSON 解析为表格结构,但面对深层次或复杂运算时,SQL 需频繁使用 UNNEST、子查询等结构,逻辑易变得繁琐。而 SPL 以集合运算方式直接处理子表,代码更简洁直观,无需复杂关联或 Lambda 语法,同时保持 JSON 原始结构。esProc SPL 开源免费,适合复杂 JSON 场景,欢迎至乾学院探索!
|
11月前
|
关系型数据库 MySQL 数据库连接
Pgloader极简教程
pgloader 是一款强大的数据同步与迁移工具,专为将数据从多种来源迁移到 PostgreSQL 设计。它支持从文件(如 CSV)和多种数据库系统(如 SQLite、MySQL)迁移数据。pgloader 提供了丰富的安装选项,包括手动编译安装,适用于不同操作系统。使用上,既可以通过命令行直接操作,也可以通过配置文件进行复杂的数据迁移任务,如表结构和数据的同步。其高效性和灵活性使得数据库迁移变得更加简便和可靠。
1370 4
|
12月前
|
存储 监控 关系型数据库
MySQL计算某条数据与上一条数据的生成时间差
MySQL计算某条数据与上一条数据的生成时间差
248 2
|
前端开发
HTML+CSS 速成10分钟!一键实现你的后台管理系统首页梦想!
HTML+CSS 速成10分钟!一键实现你的后台管理系统首页梦想!
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(三十四)(1)
SqlAlchemy 2.0 中文文档(三十四)
233 0
|
JavaScript 前端开发 索引
JavaScript中的正则表达式:使用与模式匹配
【4月更文挑战第22天】本文介绍了JavaScript中的正则表达式及其模式匹配,包括字面量和构造函数定义方式,以及`test()`、`match()`、`search()`和`replace()`等匹配方法。正则表达式由元字符(如`.`、`*`、`[]`)和标志(如`g`、`i`)组成,用于定义搜索模式。文中还分享了正则使用的技巧,如模式分解、非捕获分组和注释。掌握正则表达式能提升文本处理的效率和代码质量。
|
算法 编译器 测试技术
跨平台构建的艺术:使用 CMake 实现项目移植的全面指南
跨平台构建的艺术:使用 CMake 实现项目移植的全面指南
610 5
H8
|
存储 传感器 机器学习/深度学习
数字孪生(Digital Twins)
数字映射(Digital twin),或译作数字孪生、数字分身,指在信息化平台内模拟物理实体、流程或者系统,类似实体系统在信息化平台中的双胞胎。借助于数字映射,可以在信息化平台上了解物理实体的状态,甚至可以对物理实体里面预定义的接口组件进行控制。
H8
813 1