4.2.7. 常量
本章主要介绍统一SQL对Oracle数据库的伪列转换到其他数据库中存在的一些差异点;具体支持字面量边界可参考 统一SQL使用边界规范
4.2.7.1. LightDB-Oracle
4.2.7.1.1. INTERVAL类型
INTERVAL类型用来指定一段时间。统一SQL支持两种类型的间隔字面量:INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND。
INTERVAL YEAR TO MONTH
语法
/*SQL 日期格式*/
INTERVAL '[+|-] years-months' YEAR [(precision)] TO MONTH
/*ISO 日期格式*/
INTERVAL 'P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]]' YEAR [(precision)] TO MONTH
描述
用来指定以年和月为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
years-months |
years 表示年,取整数值,范围为 [0,178000000]。months 表示月,取整数值,范围为 [0 , 11]。注意 值中不允许有空格。 |
precision |
表示 YEAR 元素的精度,默认值为 2,取值范围为 [0,9] |
P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]] |
ISO 日期格式,范围见下列,注意 值中不允许有空格。 |
years 表示年数,取整数值,范围为 [0,178000000]。
months 表示月数,取整数值,范围为 [0,11]。
days 表示日数,取整数值,范围为 [0,366]。
hours 表示秒数,取整数值,范围为 [0,59]。
minutes 表示分钟数,取整数值,范围为 [0,59]。
seconds 表示秒数,取整数值,范围为 [0,59]。
frac_secs 表示秒的精度,取整数值,范围为 [0,999999999]。
示例
CREATE TABLE unisql_interval_ym_table (
col1 INTERVAL YEAR(1) TO MONTH,
col2 INTERVAL YEAR(2) TO MONTH,
col3 INTERVAL YEAR(3) TO MONTH
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ym_table(col1,col2,col3) VALUES
(
INTERVAL '2-3' YEAR TO MONTH,
INTERVAL '-21-3' YEAR(2) TO MONTH,
INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR(2) TO MONTH
);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
COL1|COL2 |COL3|
----+-----+----+
2-3 |-21-3|3-11|
-- 转换后LightDB-Oracle SQL:
INSERT INTO unisql_interval_ym_table (col1,col2,col3) VALUES (INTERVAL '2-3' YEAR TO MONTH,INTERVAL '-21-3' YEAR TO MONTH,INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR TO MONTH);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
col1 |col2 |col3 |
--------------+-----------------+---------------+
2 years 3 mons|-21 years -3 mons|3 years 11 mons|
INTERVAL DAY TO SECOND
语法
INTERVAL '[+ | -] days hours:minutes:seconds[.frac_secs]' DAY [(precision)] TO SECOND [(fractional_seconds_precision)]
描述
用来指定以天和具体时间为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
days hours:minutes:seconds[.frac_secs] |
SQL日期格式,依次表示天数、时、分、秒。注意 值中时、分、秒不允许有空格。 |
precision |
表示 DAY 元素的精度,默认值为 2,取值范围为 [0,9] |
fractional_seconds_precision |
表示 SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9] |
days 表示天,取整数值,范围为 [0,999999999]。
hours 表示小时,取整数值,范围为 [0,23]。
minutes 表示分钟,取整数值,范围为 [0,59]。
seconds 表示秒,取整数值,范围为 [0,59]。
示例
CREATE TABLE unisql_interval_ds_table (
col1 INTERVAL DAY(3) TO SECOND(9),
col2 INTERVAL DAY(1) TO SECOND(9)
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ds_table(col1,col2)
VALUES
(
INTERVAL '1 12:30:15.123456789' DAY(2) TO SECOND(9),
INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6)
);
SELECT col1,col2 FROM unisql_interval_ds_table;
COL1 |COL2 |
--------------------+-----------------+
1 12:30:15.123456789|-4 5:45:30.987654|
-- 转换后LightDB-Oracle SQL:
INSERT INTO unisql_interval_ds_table (col1,col2) VALUES (INTERVAL '1 12:30:15.123456789' DAY TO SECOND(6),INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6));
SELECT col1,col2 FROM unisql_interval_ds_table;
col1 |col2 |
---------------------+------------------------+
1 day 12:30:15.123457|-4 days +05:45:30.987654|
警告
下面列举的是一些在使用间隔字面量过程中会遇到的部分疑问点,在使用数据库时,如果对数据完全一致要求较高,现有的函数处理能力不能满足业务需求,建议进行业务SQL改写或者对结果进行进一步处理
目标数据库对显示间隔字面量与源库Oracle不一致,但是语义保持一致,不考虑时区、数据库设置的影响;
精度、时间格式暂时不做范围限制,具体是否错误由执行层保证;
因为需求原因,时间间隔字面量只限制在插入表中值去使用;
Oracle的INTERVAL DAY TO SECOND字面量的SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9],但是目标库相关SECOND 元素小数部分的精度的最大值为6,所以目标数据库字面量值超过该精度会自动进行处理后截断,出现与源数据库数据不一致的情况。
4.2.7.2. PostgreSQL
4.2.7.2.1. INTERVAL类型
INTERVAL类型用来指定一段时间。统一SQL支持两种类型的间隔字面量:INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND。
INTERVAL YEAR TO MONTH
语法
/*SQL 日期格式*/
INTERVAL '[+|-] years-months' YEAR [(precision)] TO MONTH
/*ISO 日期格式*/
INTERVAL 'P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]]' YEAR [(precision)] TO MONTH
描述
用来指定以年和月为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
years-months |
years 表示年,取整数值,范围为 [0,178000000]。months 表示月,取整数值,范围为 [0 , 11]。注意 值中不允许有空格。 |
precision |
表示 YEAR 元素的精度,默认值为 2,取值范围为 [0,9] |
P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]] |
ISO 日期格式,范围见下列,注意 值中不允许有空格。 |
years 表示年数,取整数值,范围为 [0,178000000]。
months 表示月数,取整数值,范围为 [0,11]。
days 表示日数,取整数值,范围为 [0,366]。
hours 表示秒数,取整数值,范围为 [0,59]。
minutes 表示分钟数,取整数值,范围为 [0,59]。
seconds 表示秒数,取整数值,范围为 [0,59]。
frac_secs 表示秒的精度,取整数值,范围为 [0,999999999]。
示例
CREATE TABLE unisql_interval_ym_table (
col1 INTERVAL YEAR(1) TO MONTH,
col2 INTERVAL YEAR(2) TO MONTH,
col3 INTERVAL YEAR(3) TO MONTH
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ym_table(col1,col2,col3) VALUES
(
INTERVAL '2-3' YEAR TO MONTH,
INTERVAL '-21-3' YEAR(2) TO MONTH,
INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR(2) TO MONTH
);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
COL1|COL2 |COL3|
----+-----+----+
2-3 |-21-3|3-11|
-- 转换后PostgreSQL SQL:
INSERT INTO unisql_interval_ym_table (col1,col2,col3) VALUES (INTERVAL '2-3' YEAR TO MONTH,INTERVAL '-21-3' YEAR TO MONTH,INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR TO MONTH);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
col1 |col2 |col3 |
--------------+-----------------+---------------+
2 years 3 mons|-21 years -3 mons|3 years 11 mons|
INTERVAL DAY TO SECOND
语法
INTERVAL '[+ | -] days hours:minutes:seconds[.frac_secs]' DAY [(precision)] TO SECOND [(fractional_seconds_precision)]
描述
用来指定以天和具体时间为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
days hours:minutes:seconds[.frac_secs] |
SQL日期格式,依次表示天数、时、分、秒。注意 值中时、分、秒不允许有空格。 |
precision |
表示 DAY 元素的精度,默认值为 2,取值范围为 [0,9] |
fractional_seconds_precision |
表示 SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9] |
days 表示天,取整数值,范围为 [0,999999999]。
hours 表示小时,取整数值,范围为 [0,23]。
minutes 表示分钟,取整数值,范围为 [0,59]。
seconds 表示秒,取整数值,范围为 [0,59]。
示例
CREATE TABLE unisql_interval_ds_table (
col1 INTERVAL DAY(3) TO SECOND(9),
col2 INTERVAL DAY(1) TO SECOND(9)
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ds_table(col1,col2)
VALUES
(
INTERVAL '1 12:30:15.123456789' DAY(2) TO SECOND(9),
INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6)
);
SELECT col1,col2 FROM unisql_interval_ds_table;
COL1 |COL2 |
--------------------+-----------------+
1 12:30:15.123456789|-4 5:45:30.987654|
-- 转换后PostgreSQL SQL:
INSERT INTO unisql_interval_ds_table (col1,col2) VALUES (INTERVAL '1 12:30:15.123456789' DAY TO SECOND(6),INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6));
SELECT col1,col2 FROM unisql_interval_ds_table;
col1 |col2 |
---------------------+------------------------+
1 day 12:30:15.123457|-4 days +05:45:30.987654|
警告
下面列举的是一些在使用间隔字面量过程中会遇到的部分疑问点,在使用数据库时,如果对数据完全一致要求较高,现有的函数处理能力不能满足业务需求,建议进行业务SQL改写或者对结果进行进一步处理
目标数据库对显示间隔字面量与源库Oracle不一致,但是语义保持一致,不考虑时区、数据库设置的影响;
精度、时间格式暂时不做范围限制,具体是否错误由执行层保证;
因为需求原因,时间间隔字面量只限制在插入表中值去使用;
Oracle的INTERVAL DAY TO SECOND字面量的SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9],但是目标库相关SECOND 元素小数部分的精度的最大值为6,所以目标数据库字面量值超过该精度会自动进行处理后截断,出现与源数据库数据不一致的情况。
4.2.7.3. Tdsql-Oracle
4.2.7.3.1. INTERVAL类型
INTERVAL类型用来指定一段时间。统一SQL支持两种类型的间隔字面量:INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND。
INTERVAL YEAR TO MONTH
语法
/*SQL 日期格式*/
INTERVAL '[+|-] years-months' YEAR [(precision)] TO MONTH
/*ISO 日期格式*/
INTERVAL 'P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]]' YEAR [(precision)] TO MONTH
描述
用来指定以年和月为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
years-months |
years 表示年,取整数值,范围为 [0,178000000]。months 表示月,取整数值,范围为 [0 , 11]。注意 值中不允许有空格。 |
precision |
表示 YEAR 元素的精度,默认值为 2,取值范围为 [0,9] |
P[ years Y][months M][days D][T[hours H][minutes M][seconds[.frac_secs]S]] |
ISO 日期格式,范围见下列,注意 值中不允许有空格。 |
years 表示年数,取整数值,范围为 [0,178000000]。
months 表示月数,取整数值,范围为 [0,11]。
days 表示日数,取整数值,范围为 [0,366]。
hours 表示秒数,取整数值,范围为 [0,59]。
minutes 表示分钟数,取整数值,范围为 [0,59]。
seconds 表示秒数,取整数值,范围为 [0,59]。
frac_secs 表示秒的精度,取整数值,范围为 [0,999999999]。
示例
CREATE TABLE unisql_interval_ym_table (
col1 INTERVAL YEAR(1) TO MONTH,
col2 INTERVAL YEAR(2) TO MONTH,
col3 INTERVAL YEAR(3) TO MONTH
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ym_table(col1,col2,col3) VALUES
(
INTERVAL '2-3' YEAR TO MONTH,
INTERVAL '-21-3' YEAR(2) TO MONTH,
INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR(2) TO MONTH
);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
COL1|COL2 |COL3|
----+-----+----+
2-3 |-21-3|3-11|
-- 转换后TDSQL-Oracle模式 SQL:
INSERT INTO unisql_interval_ym_table (col1,col2,col3) VALUES (INTERVAL '2-3' YEAR TO MONTH,INTERVAL '-21-3' YEAR TO MONTH,INTERVAL 'P3Y11M366DT23H59M59.1234S' YEAR TO MONTH);
SELECT col1,col2,col3 FROM unisql_interval_ym_table;
col1 |col2 |col3 |
--------------+-----------------+---------------+
2 years 3 mons|-21 years -3 mons|3 years 11 mons|
INTERVAL DAY TO SECOND
语法
INTERVAL '[+ | -] days hours:minutes:seconds[.frac_secs]' DAY [(precision)] TO SECOND [(fractional_seconds_precision)]
描述
用来指定以天和具体时间为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
days hours:minutes:seconds[.frac_secs] |
SQL日期格式,依次表示天数、时、分、秒。注意 值中时、分、秒不允许有空格。 |
precision |
表示 DAY 元素的精度,默认值为 2,取值范围为 [0,9] |
fractional_seconds_precision |
表示 SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9] |
days 表示天,取整数值,范围为 [0,999999999]。
hours 表示小时,取整数值,范围为 [0,23]。
minutes 表示分钟,取整数值,范围为 [0,59]。
seconds 表示秒,取整数值,范围为 [0,59]。
示例
CREATE TABLE unisql_interval_ds_table (
col1 INTERVAL DAY(3) TO SECOND(9),
col2 INTERVAL DAY(1) TO SECOND(9)
);
-- 转换前Oracle SQL:
INSERT INTO unisql_interval_ds_table(col1,col2)
VALUES
(
INTERVAL '1 12:30:15.123456789' DAY(2) TO SECOND(9),
INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6)
);
SELECT col1,col2 FROM unisql_interval_ds_table;
COL1 |COL2 |
--------------------+-----------------+
1 12:30:15.123456789|-4 5:45:30.987654|
-- 转换后TDSQL-Oracle模式 SQL:
INSERT INTO unisql_interval_ds_table (col1,col2) VALUES (INTERVAL '1 12:30:15.123456789' DAY TO SECOND(6),INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6));
SELECT col1,col2 FROM unisql_interval_ds_table;
col1 |col2 |
---------------------+------------------------+
1 day 12:30:15.123457|-4 days +05:45:30.987654|
警告
下面列举的是一些在使用间隔字面量过程中会遇到的部分疑问点,在使用数据库时,如果对数据完全一致要求较高,现有的函数处理能力不能满足业务需求,建议进行业务SQL改写或者对结果进行进一步处理
目标数据库对显示间隔字面量与源库Oracle不一致,但是语义保持一致,不考虑时区、数据库设置的影响;
精度、时间格式暂时不做范围限制,具体是否错误由执行层保证;
因为需求原因,时间间隔字面量只限制在插入表中值去使用;
Oracle的INTERVAL DAY TO SECOND字面量的SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9],但是目标库相关SECOND 元素小数部分的精度的最大值为6,所以目标数据库字面量值超过该精度会自动进行处理后截断,出现与源数据库数据不一致的情况。
4.2.7.4. OceanBase-Oracle
4.2.7.4.1. INTERVAL类型
INTERVAL类型用来指定一段时间。统一SQL支持两种类型的间隔字面量:INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND。
INTERVAL YEAR TO MONTH
语法
INTERVAL '[+|-] years-months' YEAR [(precision)] TO MONTH
描述
用来指定以年和月为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
years-months |
years 表示年,取整数值,范围为 [0,999999999]。months 表示月,取整数值,范围为 [0 , 11]。注意 值中不允许有空格。 |
precision |
表示 YEAR 元素的精度,默认值为 2,取值范围为 [0,9] |
示例
-- 转换前Oracle SQL:
select
INTERVAL '2-3' YEAR(1) TO MONTH,
INTERVAL '+19-11' YEAR TO MONTH,
INTERVAL '-21-3' YEAR(2)TO MONTH,
INTERVAL '123456789-11' YEAR(9) TO MONTH
from dual;
INTERVAL'2-3'YEAR(1)TOMONTH|INTERVAL'19-11'YEARTOMONTH|INTERVAL'-21-3'YEAR(2)TOMONTH|INTERVAL'123456789-11'YEAR(9)TOMONTH|
---------------------------+--------------------------+-----------------------------+------------------------------------+
2-3 |19-11 |-21-3 |123456789-11 |
-- 转换后OceanBase-Oracle SQL:
select
INTERVAL '2-3' YEAR(1) TO MONTH,
INTERVAL '+19-11' YEAR TO MONTH,
INTERVAL '-21-3' YEAR(2)TO MONTH,
INTERVAL '123456789-11' YEAR(9) TO MONTH
from dual;
INTERVAL'2-3'YEAR(1)TOMONTH|INTERVAL'+19-11'YEARTOMONTH|INTERVAL'-21-3'YEAR(2)TOMONTH|INTERVAL'123456789-11'YEAR(9)TOMONTH|
---------------------------+---------------------------+-----------------------------+------------------------------------+
2-3 |19-11 |-21-3 |123456789-11 |
INTERVAL DAY TO SECOND
语法
INTERVAL '[+ | -] days hours:minutes:seconds[.frac_secs]' DAY [(precision)] TO SECOND [(fractional_seconds_precision)]
描述
用来指定以天和具体时间为单位的一段时间。
参数解释
参数 |
说明 |
---|---|
days hours:minutes:seconds[.frac_secs] |
SQL日期格式,依次表示天数、时、分、秒。注意 值中不允许有空格。 |
precision |
表示 DAY 元素的精度,默认值为 2,取值范围为 [0,9] |
fractional_seconds_precision |
表示 SECOND 元素小数部分的精度,默认值为 6,取值范围为 [0,9] |
days 表示天,取整数值,范围为 [0,999999999]。
hours 表示小时,取整数值,范围为 [0,23]。
minutes 表示分钟,取整数值,范围为 [0,59]。
seconds 表示秒,取整数值,范围为 [0,59]。
示例
-- 转换前Oracle SQL:
SELECT
INTERVAL '+123456789 12:30:15.123456789' DAY(9) TO SECOND(9),
INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6)
FROM dual;
INTERVAL'+12345678912:30:15.123456789'DAY(9)TOSECOND(9)|INTERVAL'-405:45:30.987654'DAYTOSECOND(6)|
-------------------------------------------------------+-----------------------------------------+
123456789 12:30:15.123456789 |-4 5:45:30.987654 |
-- 转换后OceanBase-Oracle SQL:
SELECT
INTERVAL '+123456789 12:30:15.123456789' DAY(9) TO SECOND(9),
INTERVAL '-4 05:45:30.987654' DAY TO SECOND(6)
FROM dual;
INTERVAL'+12345678912:30:15.123456789'DAY(9)TOSECOND(9)|INTERVAL'-405:45:30.987654'DAYTOSECOND(6)|
-------------------------------------------------------+-----------------------------------------+
123456789 12:30:15.123456789 |-4 5:45:30.987654 |