是否有用于此目的的特定数据类型,或者我需要使用两个不同的列,例如from_time和to_time?
Oracle 没有范围数据类型(例如 PostgreSQL)。它甚至没有时间数据类型。甲骨文中的时间总是伴随着日期。因此,您需要两列(start_time 和 end_time),其中您主要有两个选项:
- 使用数据类型
DATE
并忽略日期部分(您应该始终将其设置为相同的日期,例如日期"1900-01-01",您可以使用插入前触发器来确保)。 - 使用数据类型
CHAR(5)
并编写约束以仅允许小时 00 到 23 和分钟 00 到 59。
在我看来,后者更清晰一些,而前者允许日期算术。做出您的选择。
以下是 Oracle 数据类型: 没有内置类型来存储此类信息。
你当然可以发明任何你喜欢的(奇怪的)编码来存储这些信息。
create table dates as (
select date '2017-01-17' + 15/24 start_date,
date '2017-01-17' + 17/24 end_date
from dual
)
select to_char(start_date, 'yyyy-mm-dd hh24:mi') || ' - ' ||
to_char(end_date, 'yyyy-mm-dd hh24:mi') as as_varchar2
from dates
select XMLTYPE('<XML><START>' ||
to_char(start_date, 'yyyy-mm-dd hh24:mi') ||
'</START><END>' ||
to_char(end_date, 'yyyy-mm-dd hh24:mi') ||
'</END></XML>') as as_XML from dates
...
但正确的方法是两列。
您需要两个单独的列,但可以为此使用 INTERVAL
类型,但要理解它表示从一天开始到所需时间的间隔。 喜欢这个:
create table matt_tab1
( from_time interval day to second,
to_time interval day to second );
insert into matt_tab1
values ( interval '17:00:00' hour to second,
interval '19:00:00' hour to second );
select from_time,
to_time,
to_time - from_time duration
from matt_tab1;
FROM_TIME TO_TIME DURATION
--------- ------- --------
+00 17:00:00.000000 +00 19:00:00.000000 +00 02:00:00.000000
如果您确实需要单列...
当然,如果需要,您可以创建一个封装这两个间隔的自定义对象类型:
CREATE OR REPLACE NONEDITIONABLE TYPE my_time_range
AS OBJECT ( from_time INTERVAL DAY TO SECOND,
to_time INTERVAL DAY TO SECOND );
CREATE TABLE matt_tab2 (a_range my_time_range);
INSERT INTO matt_tab2 (a_range)
VALUES (my_time_range (INTERVAL '17:00:00' HOUR TO SECOND,
INTERVAL '19:00:00' HOUR TO SECOND));
SELECT t.a_range.from_time,
t.a_range.to_time,
t.a_range.to_time - t.a_range.from_time duration
FROM matt_tab2 t;
然后,您还可以在该对象类型上编写有用的方法,例如overlaps_with(a_range my_time_range)
或starts_before
等。
VarChar2() 格式并使用"-"分隔 2 种日期格式,例如您可以将其显示为"01/01/2000 - 02/02/2000"。下面是填充列的代码:
select TO_CHAR(sysdate+1, 'dd/mm/yyyy') ||' - '|| TO_CHAR(sysdate+1, 'dd/mm/yyyy')
from dual;
然后,您可以使用 folling 语句将其解析回"DATE"格式:
select to_date(regexp_substr('01/01/2000 - 02/02/2000','^d+/d+/d+'),'dd/mm/yyyy') as date1,
to_date(regexp_substr('01/01/2000 - 02/02/2000','d+/d+/d+$'),'dd/mm/yyyy') as date2
from dual;