MySQL的FROM_UNIXTIME和UNIX_TIMESTAMP如何在YashanDB改写
前言
MySQL应用常使用FROM_UNIXTIME和UNIX_TIMESTAMP函数,但是无法在YashanDB直接执行,需要改写。本文探讨如何利用YashanDB高度兼容Oracle的特点快速完成函数改写的方案。
问题
MySQL示例使用FROM_UNIXTIME和UNIX_TIMESTAMP,执行成功
mysql> select FROM_UNIXTIME( 8640000 + UNIX_TIMESTAMP('2024-01-01 00:00:00')) from dual; +-------------------------------------------------------------------+ | FROM_UNIXTIME( 8640000 + UNIX_TIMESTAMP('2024-01-01 00:00:00')) | +-------------------------------------------------------------------+ | 2024-04-10 00:00:00 | +-------------------------------------------------------------------+ 1 row in set (0.00 sec) |
YashanDB报错
SQL> select FROM_UNIXTIME( 8640000 + UNIX_TIMESTAMP('2024-01-01 00:00:00')) from dual;
[1:8]YAS-04243 invalid identifier "FROM_UNIXTIME" |
解决方法
思考
MySQL的常用函数FROM_UNIXTIME和UNIX_TIMESTAMP,没有在YashanDB实现。但是,由于YashanDB高度兼容Oracle,而应用从MySQL数据库切换到Oracle数据库,也是常见的数据库切换。因此,可以先借鉴Oracle如何兼容MySQL的常用函数FROM_UNIXTIME和UNIX_TIMESTAMP。
改写方案
通过搜索,找到Oracle的改写方法:https://forums.oracle.com/ords/apexds/post/functions-unix-timestamp-and-from-unixtime-from-mysql-to-or-2594。利用YashanDB高度兼容Oracle的特点,借鉴Oracle的改写方法,实现YashanDB的FROM_UNIXTIME和UNIX_TIMESTAMP函数:
CREATE OR REPLACE FUNCTION SYS.FROM_UNIXTIME ( TIMESTAMP_ IN NUMBER ) RETURN DATE AS SECONDS_PER_DAY NUMBER := 86400; MASK VARCHAR2(50 CHAR) := 'YYYY-MM-DD HH24:MI:SS'; REF_DATE DATE; BEGIN REF_DATE := TO_DATE('1970-01-01 00:00:00', MASK); RETURN REF_DATE + (TIMESTAMP_/SECONDS_PER_DAY); END FROM_UNIXTIME; /
CREATE OR REPLACE FUNCTION SYS.UNIX_TIMESTAMP ( DATE_ IN DATE ) RETURN NUMBER AS SECONDS_PER_DAY NUMBER := 86400; DIFF_BETWEEN_DATES NUMBER; MASK VARCHAR2(50 CHAR) := 'YYYY-MM-DD HH24:MI:SS'; REF_DATE DATE; BEGIN REF_DATE := TO_DATE('1970-01-01 00:00:00', MASK); DIFF_BETWEEN_DATES := DATE_ - REF_DATE; RETURN DIFF_BETWEEN_DATES * SECONDS_PER_DAY; END UNIX_TIMESTAMP; /
CREATE PUBLIC SYNONYM FROM_UNIXTIME FOR SYS.FROM_UNIXTIME; CREATE PUBLIC SYNONYM UNIX_TIMESTAMP FOR SYS.UNIX_TIMESTAMP; |
成果
实现YashanDB的FROM_UNIXTIME和UNIX_TIMESTAMP函数,YashanDB报错的问题得到解决
SQL> select FROM_UNIXTIME( 8640000 + UNIX_TIMESTAMP('2024-01-01 00:00:00')) from dual;
FROM_UNIXTIME(864000 ------------------------------------------------ 2024-04-10 00:00:00
1 row fetched. |