ORACLE 迁移到 MogDB 中遇到在 ORACLE 中不是关键字,但是在 MogDB 是关键字的情况,目前遇到两个如下:

MogDB 保留字:INTERVAL

源库SQL-ORACLE

1
2
3
4
5
6
7
CREATE OR REPLACE FUNCTION SPLITIME(START_TIME IN VARCHAR2,
END_TIME IN VARCHAR2,
INTERVAL IN NUMBER,
…………
N := ((END_DATE-START_DATE) * 24 * 60) / INTERVAL + 1;
FOR I IN 1 .. N LOOP
…………

目标库SQL:MogDB

INTERVAL 在 MogDB 中是保留字,替换即可。将 INTERVAL 替换为 TIME_INTERVAL,功能正常。

MogDB 保留字:CURRENT_TIME

CURRENT_TIME 在 MogDB 中是保留字,返回的类型是:time with time zone,也就是返回带有时区的值。

1
2
3
4
5
6
7
8
9
10
11
12
……
SQL_STMT VARCHAR2(4000);
CURRENT_TIME DATE;
CT_DAY NUMBER;
BEGIN
FOR C IN (SELECT CREATE_TIME
FROM TABLE(SPLITIME(TO_CHAR(START_DAY,'YYYY-MM-DD'),TO_CHAR(END_DAY, 'YYYY-MM-DD'),
1440,
'YYYY-MM-DD HH24:MI:SS'))) LOOP
CURRENT_TIME := C.CREATE_TIME;
CT_DAY := TO_NUMBER(TO_CHAR(CURRENT_TIME, 'YYYYMMDD'));
……

定义了 CURRENT_TIME 变量,类型为:TIMESTAMP(0) WITHOUT TIME ZONE,但是 这跟保留字冲突,下面的 to_number 进行转换的时候会报错,原因在于:TO_CHAR函数不能直接处理时间带时区的类型(time with time zone)。CURRENT_TIME 在 PostgreSQL 中返回当前时间,这个时间是带时区的。

改造如下:

1
2
3
4
5
6
7
8
9
10
11
……
SQL_STMT VARCHAR(4000);
V_CURRENT_TIME TIMESTAMP(0) WITHOUT TIME ZONE;
CT_DAY NUMERIC;
BEGIN
FOR C IN (SELECT CREATE_TIME
FROM UNNEST(SPLIT_TIME(TO_CHAR(START_DAY, 'YYYY-MM-DD'),TO_CHAR(END_DAY, 'YYYY-MM-DD'),
1440,'YYYY-MM-DD'))) LOOP
V_CURRENT_TIME := C.CREATE_TIME;
CT_DAY := TO_NUMBER(TO_CHAR(V_CURRENT_TIME, 'YYYYMMDD'));
……

即把 CURRENT_TIME 改为 V_CURRENT_TIME 即可。

保留字可以通过数据库的视图来查看,具体如下:

ORACLE 保留字:

1
select count * from v$reserved_words order by keyword asc; 

MogDB/PG 保留字:

1
SELECT * FROM pg_get_keywords() WHERE catcode = 'R';
1
2
3
4
5
6
mogdb=> SELECT count(1) FROM pg_get_keywords() WHERE catcode = 'R';
count
-------
98
(1 row)

官方手册关键字资料:
http://postgres.cn/docs/9.3/sql-keywords-appendix.html

https://docs.mogdb.io/zh/mogdb/v5.0/keywords-1

https://docs.mogdb.io/zh/mogdb/v5.0/keywords-2

还遇到一个时间函数的改造,如下:

时间函数改造

源库-ORACLE

1
SELECT TRUNC(SYSDATE, 'hh24') INTO CURRENT_TIME 

改造后:

1
SELECT date_trunc('hour',sysdate)

原文作者: Hi.MogDB

原文链接: https://hi.mogdb.org/posts/3a3821a2/

许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议