暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

Halo数据库是目前Oracle兼容性最好的数据库之一

冷狼 2024-10-29
750

一、Halo数据库拥有多模解析引擎功能

  Halo数据库具有独有的多模解析引擎技术,可以兼容PostgreSQL、Oracle、Sybase、MySQL、SQL Server、DB2 等主流数据库语法从而大幅减少迁移项目中的代码修改量。目前主要兼容Oracle语法,针对Oracle数据库的迁移至少可以减少95%以上的代码修改量,极大降低迁移成本,同时也大大降低了迁移风险。

  Halo 使用可配置式解析引擎,可以灵活地在各个数据库引擎之间切换。

二、如何启用 Oracle 解析引擎

2.1 将参数文件 postgresql.conf 中参数database_compat_mode 设置为 'oracle'

database_compat_mode = 'oracle'

2.2 重启数据库

pg_ctl restart

2.3 针对需要启用Oracle 解析引擎的数据库创建Oracle扩展

create extension aux_oracle cascade;

三、其他与Oracle引擎相关的参数

3.1 transform_null_equals

由于针对NULL的任何操作都只会返回NULL,所以要判断一个值是否为NULL一般只能用IS NULL来判断。

Halo提供了参数transform_null_equals来控制是否可以用“=”操作符来判断一个值是否为NULL。可以将参数transform_null_equals 设置为 on(默认为off)。

3.1.1数据库中有一条空值记录,当参数transform_null_equals 状态等于off时,使用“=null”不能查询出空值记录
halo0root=# select * from test where id=null;
 id
----
(0 行记录)
3.1.2数据库中有一条空值记录,当参数transform_null_equals 状态等于on时,使用“=null”可以查询出空值记录
halo0root=# select * from test where id=null;
 id
----

(1 行记录)

3.2 use_datetime_as_date

Oracle的date 类型带有日期和时间信息,这和Halo的默认设置不同。默认情况下,Halo的date类型只包含日期,datetime类型才包含日期和时间信息。如果想要实现和Oracle相同的date类型,可以将参数use_datetime_as_date设置为true (默认值是 off)。

use_datetime_as_date = true

四、Halo数据库选择Oracle模式

 Halo数据库 支持 Oracle 中绝大部分函数和语法、包、视图等等。这意味着在从 Oracle 过渡到 Halo的过程中,您不需要消耗大量的时间去学习新的内容,并且可以流畅的实现从 Oracle 到 Halo 的迁移。

  4.1 兼容Oracle函数

 Halo数据库支持兼容的函数:字符类型、数值类型、日期类型、时间戳类型、间隔类型、大对象类型、二进制类型、转换函数、聚集函数、时间函数等等。

    以下我们进行一些简单的函数示例:

  ADD_MONTHS函数在给定日期的基础上增加(如果第二个参数为负数则减少)指定的月数。在执行计算之前,月数参数的任何小数部分都会被截断。如果给定的日期包含时间部分,则将转到结果中。

halo0root=#SELECT ADD_MONTHS('13-JUN-07',4) FROM DUAL;
       add_months
------------------------
 2013-10-07 00:00:00+08
(1 行记录)

 BITAND函数执行按位和操作,并根据输入参数的数据类型返回一个值。

语法:BITAND(<expr1>, <expr2>)

返回类型:BITAND函数返回与输入参数的数据类型相同的值。

halo0root=#SELECT BITAND(10,11) FROM DUAL;
 bitand
--------
     10
(1 行记录)

BTRIM 函数通过删除前导空格和尾随空格或删除与可选的指定字符串匹配的字 符来剪裁字符串。

语法:BTRIM(string [, matching_string ] )

halo0root=#select 'xyzaxyzbxyzcxyz' as untrim,btrim('xyzaxyzbxyzcxyz', 'xyz') as trim;
     untrim     |   trim
-----------------+-----------
 xyzaxyzbxyzcxyz | axyzbxyzc

CONCAT函数将多个RAW值连接成单个RAW值。

  这个函数返回一个RAW值。

halo0root=#select concat('aba','df') from dual;
 concat
--------
 abadf
(1 行记录)

4.2 兼容Oracle语法:

 Halo数据库支持兼容的语法:外连接符(+)、序列、SYSDATE(查看日期)、NULL与空串、DECODE、ROWNUM、DBLINK、DUAL伪表、IN特别语法等等。

以下我们进行一些简单的语法示例:

 外连接符(+):包括左外连接(左表不加限制),右外连接(右表不加限制),并且可以支持非常复杂的连接操作。

现建立ta; tb; tc; td; te; tf; tg; th; ti; tj  共10张表:

halo0root=# CREATE TABLE ta (id NUMBER, name VARCHAR2(30), location VARCHAR2(30));
CREATE TABLE
halo0root=# INSERT INTO ta VALUES (1, 'A', 'CN');
INSERT 0 1
halo0root=# INSERT INTO ta VALUES (2, 'B', 'CN');
INSERT 0 1
halo0root=# INSERT INTO ta VALUES (3, 'C', 'US');
INSERT 0 1
halo0root=# INSERT INTO ta VALUES (4, 'D', 'JP');
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE tb (id NUMBER, aid NUMBER, class VARCHAR2(30), location VARCHAR2(30));
CREATE TABLE
halo0root=# INSERT INTO tb VALUES (1, 1, 'S1', 'CN');
INSERT 0 1
halo0root=# INSERT INTO tb VALUES (2, 2, 'S1', 'CN');
INSERT 0 1
halo0root=# INSERT INTO tb VALUES (3, 3, 'S2', 'US');
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE tc (id NUMBER, name VARCHAR2(30), bid NUMBER, location VARCHAR2(30));
CREATE TABLE
halo0root=# INSERT INTO tc VALUES (1, 'T1', 1, 'CN');
INSERT 0 1
halo0root=# INSERT INTO tc VALUES (2, 'T1', 2, 'CN');
INSERT 0 1
halo0root=# INSERT INTO tc VALUES (3, 'T2', 3, 'US');
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE td (id NUMBER, grade NUMBER, cid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO td VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO td VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO td VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE te (id NUMBER, grade2 NUMBER, did NUMBER);
CREATE TABLE
halo0root=# INSERT INTO te VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO te VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO te VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE tf (id NUMBER, grade3 NUMBER, eid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO tf VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO tf VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO tf VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE tg (id NUMBER, grade4 NUMBER, fid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO tg VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO tg VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO tg VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE th (id NUMBER, grade5 NUMBER, gid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO th VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO th VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO th VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE ti (id NUMBER, grade6 NUMBER, hid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO ti VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO ti VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO ti VALUES (3, 2, 3);
INSERT 0 1
halo0root=# 
halo0root=# CREATE TABLE tj (id NUMBER, grade7 NUMBER, iid NUMBER);
CREATE TABLE
halo0root=# INSERT INTO tj VALUES (1, 1, 1);
INSERT 0 1
halo0root=# INSERT INTO tj VALUES (2, 1, 2);
INSERT 0 1
halo0root=# INSERT INTO tj VALUES (3, 2, 3);
INSERT 0 1

左连接:

halo0root=# SELECT a.name, a.location, b.class FROM ta a, tb b WHERE a.id = b.aid(+);
 name | location | class 
------+----------+-------
 A    | CN       | S1
 B    | CN       | S1
 C    | US       | S2
 D    | JP       | 
(4 行记录)

右连接:

halo0root=# SELECT a.name, a.location, b.class FROM ta a, tb b WHERE a.id = b.aid( + );
 name | location | class 
------+----------+-------
 A    | CN       | S1
 B    | CN       | S1
 C    | US       | S2
 D    | JP       | 
(4 行记录)

复杂的连接:

halo0root=# SELECT a.name, b.class, c.name, d.grade, e.grade2, f.grade3, g.grade4, h.grade5, i.grade6, j.grade7
halo0root-#   FROM ta a, tb b, tc c, td d, te e, tf f, tg g, th h, ti i, tj j
halo0root-#  WHERE b.location(+) = 'CN'
halo0root-#    AND f.id = g.id(+)
halo0root-#    AND a.id = e.id(+)
halo0root-#    AND c.id = e.id(+) 
halo0root-#    AND c.id = d.id(+) 
halo0root-#    AND a.id = b.id(+)
halo0root-#    AND d.id = f.id(+)
halo0root-#    AND a.id + e.id = b.id(+)
halo0root-#    AND e.id = g.id(+)
halo0root-#    AND g.id = h.id(+)
halo0root-#    AND a.id = h.id(+)
halo0root-#    AND i.hid(+) = 2
halo0root-#    AND d.id = i.id(+)
halo0root-#    AND h.id = j.id(+)
halo0root-#    AND i.id = j.id(+);
 name | class | name | grade | grade2 | grade3 | grade4 | grade5 | grade6 | grade7 
------+-------+------+-------+--------+--------+--------+--------+--------+--------
 A    |       | T1   |     1 |      1 |      1 |      1 |      1 |        |       
 B    |        | T1   |     1 |        |      1 |        |        |        |       
 C    |       | T1   |     1 |        |      1 |        |        |        |       
 D    |        | T1   |     1 |        |      1 |        |        |        |       
 A    |       | T1   |     1 |        |      1 |        |        |      1 |       
 B    |        | T1   |     1 |      1 |      1 |      1 |      1 |      1 |      1
 C    |       | T1   |     1 |        |      1 |        |        |      1 |       
 D    |        | T1   |     1 |        |      1 |        |        |      1 |       
 A    |       | T2   |     2 |        |      2 |        |        |        |       
 B    |        | T2   |     2 |        |      2 |        |        |        |       
 C    |       | T2   |     2 |      2 |      2 |      2 |      2 |        |       
 D    |        | T2   |     2 |        |      2 |        |        |        |       
(12 行记录)

4.3 序列

序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字)。不占用磁盘空间,占用内存。其主要用途是生成表的主键值。另外,也支持ORDER关键字创建序列。

 创建一个序列:

halo0root=#CREATE SEQUENCE a_seq;
CREATESEQUENCE

也支持ORDER关键字创建序列
CREATE SEQUENCE a_seq2 ORDER;

select a_seq.nextval,a.* from t_a a order by id;

 初始化序列:

halo0root=#SELECT a_seq.nextval FROM dual;
 nextval
---------
       1
(1 行记录)

查询当前序列:


halo0root=#SELECT a_seq.currval FROM dual;
 currval
---------
       1
(1 行记录)

MINUS在Oracle中也是用来做减法操作的,只不过它不是传统意义上对数字的减法,而是对查询结果集的减法。

halo0root=#select * from td;
 id
----
  1
  2
  3
(3 行记录)
 
halo0root=#select * from te;
 id
----
  1
  2
  0
(3 行记录)
 
halo0root=#select * from td MINUS SELECT * FROM te;
 id
----
  3
(1 行记录)

<winagg_function>(distinct..) over(partition by)语法功能为求分组去重后目标的结果,支持常用的聚合函数,如count, sum, listagg等。

建立per表格

halo0root=# CREATE TABLE Per(Id int,Name varchar(255));
CREATE TABLE
halo0root=# INSERT INTO Per VALUES (1, 'ww');
INSERT 0 1
halo0root=# INSERT INTO Per VALUES (1, 'ee');
INSERT 0 1
halo0root=# INSERT INTO Per VALUES (1, 'ee');
INSERT 0 1
halo0root=# INSERT INTO Per VALUES (2, 'ee');
INSERT 0 1
halo0root=# INSERT INTO Per VALUES (2, 'dd');
INSERT 0 1

halo0root=# select * from Per;
 id | name 
----+------
  1 | ww
  1 | ee
  2 | ee
  2 | dd
  1 | ee
(5 rows)

count(distinct.. ) over(partition by)语法求分组去重后的结果:

halo0root=# select name, count(distinct name) over(partition by id) from Per;
 name | count 
------+-------
 ww   |     2
 ee   |     2
 ee   |     2
 ee   |     2
 dd   |     2
(5 rows)

作为对比,无DISTINCT操作的结果

halo0root=# select name, count(name) over(partition by id) from Per;
 name | count 
------+-------
 ww   |     3
 ee   |     3
 ee   |     3
 ee   |     2
 dd   |     2
(5 rows)

4.4 兼容Oracle系统包

Halo数据库支持兼容的系统包:

DBMS_ALERT、DBMS_ASSERT、DBMS_OUTPUT、DBMS_PIPE、DBMS_RANDOM、DBMS_UTILITY、UTL_FILE等等。

 以下我们用DBMS_ASSERT包简单示例:

DBMS_ASSERT包提供了一个接口来验证输入值的属性。

halo0root=# \df dbms_assert.*

dbms_assert.enquote_literal:用于字符串字面值添加了首引号和尾单引号。

dbms_assert.qualified_sql_name:验证输入的字符串是否为合格的SQL名称。

halo0root=#select dbms_assert.qualified_sql_name ('wy') from dual;
 qualified_sql_name
--------------------
 wy
(1 行记录)

4.5 兼容的Oracle视图

 Halo数据库支持兼容的视图:DBA_SEGMENTS、PRODUCT_COMPONENT_VERSION、user_con_columns、USER_CONSTRAINTS、USER_IND_COLUMNS、USER_OBJECTS、USER_PROCEDURES、USER_SOURCE、USER_TAB_COLUMNS、USER_TABLES等等。

 以下我们用DBA_SEGMENTS、PRODUCT_COMPONENT_VERSION进行示例:

DBA_SEGMENTS 视图描述的是数据库中所有段的存储和分配信息。


halo0root=# \dS dba_segments
                      视图 "oracle.dba_segments"
      栏位       |         类型          | 校对规则 | 可空的 | 预设
-----------------+-----------------------+----------+--------+------
 owner           | name                  |          |        |
 segment_name    | name                  |          |        |
 segment_type    | character varying(18) |          |        |
 tablespace_name | name                  |          |        |
 header_file     | oid                   |          |        |
 header_block    | oid                   |          |        |
 bytes           | bigint                |          |        |
 blocks          | integer               |          |        |

PRODUCT_COMPONENT_VERSION包含组件产品的版本和状态信息。


halo0root=# \dS product_component_version
  视图 "oracle.product_component_version"
  栏位   | 类型 | 校对规则 | 可空的 | 预设
---------+------+----------+--------+------
 product |text | C         |        |
 version |text | C         |        |
 status | text |           |        |
备注:
Product 产品的名称
Version 产品的版本号
Status 产品状态包括兼容性高可用性

以上只是展示部分兼容Oracle 功能,如您想要了解更多,请留言关注!谢谢

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论