Oracle兼容-语法-DATETIME加减运算
1. 语法
1. SELECT SYSDATE + 1 FROM DUAL;
2. SELECT SYSDATE - 1 FROM DUAL;
3. SELECT SYSDATE - SYSDATE FROM DUAL;
2. 定义和用法
在GreatSQL中支持对 DATETIME 类型数据做加减运算,例如增加1秒、1天,使用该运算行为模式需要切换到ORACLE模式下。
- 只支持加减运算,不支持其他运算类型。
- 对
TIME类型运算前,会先被转换成DATETIME类型。 - 会先将时间戳的值转换为日期值,并将
NUMBER算术日期时间和间隔表达式中的常量解释为天数。 - 年份范围为:[0,9999],不支持公元前的年份,溢出时将返回NULL,并产生warning。
- 当计算结果包含无限循环小数时,默认只保留10位,即:
div_precincrement选项默认值(4) + 6 = 10。 - 对YEAR类型加减运算时,默认转换将失败而无法运算时,会返回NULL , 并产生warning。
1. greatsql> SET sql_mode = ORACLE;
3. -- 例1:多个查询结果集合并,或者数值作为查询条件时
4. greatsql> SELECT TO_DATE('00:00:00','HH24:MI:SS') - TO_DATE('00:00:01','HH24:MI:SS') FROM DUAL
5. UNION ALL
6. SELECT TO_DATE('00:00:00','HH24:MI:SS') - TO_DATE('00:00:01','HH24:MI:SS') FROM DUAL;
7. +----------------------------------------------------------------------+
8. | to_date('00:00:00','HH24:MI:SS') - to_date('00:00:01','HH24:MI:SS') |
9. +----------------------------------------------------------------------+
10. | -0.0000115741 |
11. | -0.0000115741 |
12. +----------------------------------------------------------------------+
14. - 例2:在单一查询计算结果作为字符串展示的时候,保留小数位长度不再限制保留10位
15. greatsql> SELECT TO_DATE('00:00:00','HH24:MI:SS') - TO_DATE('00:00:01','HH24:MI:SS');
16. +----------------------------------------------------------------------+
17. | to_date('00:00:00','HH24:MI:SS') - to_date('00:00:01','HH24:MI:SS') |
18. +----------------------------------------------------------------------+
19. | -0.000011574074074074 |
20. +----------------------------------------------------------------------+
DATETIME类型运算兼容矩阵
| Operand & Operator | DATETIME | TIMESTAMP | TIME | NUMBER |
|---|---|---|---|---|
| DATETIME | - | - | - | - |
| + | - | - | - | DATETIME |
| — | DECIMAL | DECIMAL | DECIMAL | DATETIME |
| - | - | - | - | |
| / | - | - | - | - |
| TIMESTAMP | - | - | - | - |
| + | - | - | - | TIMESTAMP |
| - | DECIMAL | DECIMAL | DECIMAL | TIMESTAMP |
| - | - | - | - | |
| / | - | - | - | - |
| DATE | ||||
| + | - | - | - | DATETIME |
| - | DECIMAL | DECIMAL | DECIMAL | DATETIME |
| - | - | - | - | |
| / | - | - | - | - |
| TIME | - | - | - | |
| + | - | - | - | DATETIME |
| - | DECIMAL | DECIMAL | DECIMAL | DATETIME |
| - | - | - | - | |
| / | - | - | - | - |
| NUMBER | - | - | - | - |
| + | DATETIME | TIMESTAMP | DATETIME | NA |
| - | DATETIME | TIMESTAMP | DATETIME | NA |
| * | - | - | - | NA |
| / | - | - | - | NA |
上表是 DATETIME 类型算术运算的兼容矩阵,破折号代表不支持的操作。
3. 与Oracle差异说明
- 默认日期差异日期保留精度不一致,在GreatSQL中默认保留10位小数精度,而Oracle中根据不同的精度数据不一样。
- 时间范围最大与最小范围不一致。在GreatSQL中年份范围是 [0,9999],而Oracle中的范围是 [-4713,9999]。
- 加减字符串运算行为不同,例如字符串’a’,在Oracle中转换失败将会报错,而在GreatSQL中将转换为 ‘0’ 并产生警告,之后再进行运算。
- 在GreatSQL中,
TIMESTAMP - TIMESTAMP返回的结果是DECIMAL类型, Oracle 中返回INTERVAL类型。
4. 示例
1. greatsql> SET sql_mode = ORACLE;
3. greatsql> SET TIMESTAMP = 1;
5. -- +1/2 等同于 +12小时
6. greatsql> SELECT SYSDATE +1/2 ;
7. +----------------------------+
8. | SYSDATE +1/2 |
9. +----------------------------+
10. | 1970-01-01 12:00:01.000000 |
11. +----------------------------+
13. -- 等同于 +1天
14. greatsql> SELECT SYSDATE +1 ;
15. +----------------------------+
16. | SYSDATE +1 |
17. +----------------------------+
18. | 1970-01-02 00:00:01.000000 |
19. +----------------------------+
21. -- 等同于 -1 天
22. greatsql> SELECT SYSDATE -1 ;
23. +----------------------------+
24. | SYSDATE -1 |
25. +----------------------------+
26. | 1969-12-31 00:00:01.000000 |
27. +----------------------------+
29. greatsql> SELECT SYSDATE - SYSDATE;
30. +-------------------+
31. | SYSDATE - SYSDATE |
32. +-------------------+
33. | 0 |
34. +-------------------+
36. -- 将'a'转换成'0'后再运算,并产生warning
37. greatsql> SELECT SYSDATE + 'a';
38. +----------------------------+
39. | SYSDATE + 'a' |
40. +----------------------------+
41. | 1970-01-01 00:00:01.000000 |
42. +----------------------------+
43. 1 row in set, 1 warning (0.00 sec)
45. greatsql> SHOW WARNINGS;
46. +---------+------+---------------------------------------+
47. | Level | Code | Message |
48. +---------+------+---------------------------------------+
49. | Warning | 1292 | Truncated incorrect DOUBLE value: 'a' |
50. +---------+------+---------------------------------------+
52. -- 不支持 乘/除 运算,
53. greatsql> SELECT SYSDATE * 10;
54. ERROR 7038 (42000): in oracle_mode: date * LONGLONG not allowed
56. greatsql> SELECT SYSDATE / 10;
57. ERROR 7038 (42000): in oracle_mode: date / LONGLONG not allowed
59. greatsql> SELECT SYSDATE + SYSDATE;
60. ERROR 7038 (42000): in oracle_mode: date + DATETIME not allowed
62. greatsql> SELECT SYSDATE + 1000000000000;
63. +-------------------------+
64. | SYSDATE + 1000000000000 |
65. +-------------------------+
66. | NULL |
67. +-------------------------+
68. 1 row in set, 1 warning (0.00 sec)
70. greatsql> SHOW WARNINGS;
71. +---------+------+--------------------------------------------+
72. | Level | Code | Message |
73. +---------+------+--------------------------------------------+
74. | Warning | 1441 | Datetime function: datetime field overflow |
75. +---------+------+--------------------------------------------+
77. -- 无法对YEAR做运算
78. greatsql> SELECT CAST(2023 AS YEAR) + 1;
79. +------------------------+
80. | CAST(2023 AS YEAR) + 1 |
81. +------------------------+
82. | NULL |
83. +------------------------+
84. 1 row in set, 1 warning (0.00 sec)
86. greatsql> SHOW WARNINGS;
87. +---------+------+----------------------------------+
88. | Level | Code | Message |
89. +---------+------+----------------------------------+
90. | Warning | 1292 | Incorrect datetime value: '2023' |
91. +---------+------+----------------------------------+
问题反馈
联系我们
扫码关注微信公众号

