• 【12c】新特性:Oracle 12c Temporal Validity 时间有效性


    在应用程序开发中,有时会碰到这样一个场景:设置一条记录的生效时间范围,比如某个产品信息,在某个时间段内是有效的,一般设计表时会在表中增加valid_start和valid_end这两个字段来限制,并通过设置这两个字段来实现具体产品的生效范围,如果查看当前生效的记录,则需要通过时间进行过滤。

    Oracle 12.1.0.1引入了Temporal Validity(时间有效性),通过这一特性,在不增加列的情况下可以实现时间有效性的的判断,下面将对这一特性进行演示。

    1 数据库版本

    ALEN@PROD2> select * from v$version;
    
    
    
    BANNER CON_ID
    
    -------------------------------------------------------------------------------- ----------
    
    Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0
    
    PL/SQL Release 12.1.0.2.0 - Production 0
    
    CORE 12.1.0.2.0 Production 0
    
    TNS for Linux: Version 12.1.0.2.0 - Production 0
    
    NLSRTL Version 12.1.0.2.0 - Production 0

    2 语法结构

    要实现时间有效性,在创建表或修改表时指定如下语法即可:

    说明:

    • valid_time_column:用于指定有效时间维度的名称,Oracle将会使用该名称创建数据类型为number的不可见虚拟列;
    • start_time_column:指定起始时间列的名称,数据类型为date或timestamp;
    • end_time_column:指定结束时间列的名称,数据类型为date或timestamp;
    • 如果不指定start_time_column和end_time_column,则会自动创建valid_time_column_START和valid_time_column_END列。

    3 创建表

    3.1 不指定start_time_column和end_time_column

    ALEN@PROD2> create table prod(id number,name varchar2(100),period for valid);
    
    
    
    Table created.
    
    ALEN@PROD2> desc prod
    
    Name Null? Type
    
    ----------------------- -------- ----------------
    
    ID NUMBER
    
    NAME VARCHAR2(100)
    
    ALEN@PROD2> select column_name,data_type,data_length,column_id,segment_column_id, hidden_column from user_tab_cols where table_name='PROD';
    
    
    
    COLUMN_NAME DATA_TYPE DATA_LENGTH COLUMN_ID SEGMENT_COLUMN_ID HIDDEN_COL
    
    ------------------------------ ------------------------------ ----------- ---------- ----------------- ----------
    
    NAME VARCHAR2 100 2 4 NO
    
    ID NUMBER 22 1 3 NO
    
    VALID NUMBER 22 YES
    
    VALID_END TIMESTAMP(6) WITH TIME ZONE 13 2 YES
    
    VALID_START TIMESTAMP(6) WITH TIME ZONE 13 1 YES

    3.2 指定start_time_column和end_time_column

    ALEN@PROD2> create table prod_new(id number,name varchar2(100),valid_start_dt date, valid_end_dt date, period for valid (valid_start_dt,valid_end_dt));
    
    
    
    Table created.
    
    ALEN@PROD2> desc prod_new;
    
    Name Null? Type
    
    ----------------------- -------- ----------------
    
    ID NUMBER
    
    NAME VARCHAR2(100)
    
    VALID_START_DT DATE
    
    VALID_END_DT DATE
    
    ALEN@PROD2> select column_name,data_type,data_length,column_id,segment_column_id, hidden_column from user_tab_cols where table_name='PROD_NEW';
    
    
    
    COLUMN_NAME DATA_TYPE DATA_LENGTH COLUMN_ID SEGMENT_COLUMN_ID HIDDEN_COL
    
    ------------------------------ ------------------------------ ----------- ---------- ----------------- ----------
    
    VALID NUMBER 22 YES
    
    ID NUMBER 22 1 1 NO
    
    NAME VARCHAR2 100 2 2 NO
    
    VALID_START_DT DATE 7 3 3 NO
    
    VALID_END_DT DATE 7 4 4 NO

    4 创建测试数据

    ALEN@PROD2> insert into prod(id,name,valid_start,valid_end) values(1,'Apple_01',date'2019-01-01',date'2019-10-31');
    
    
    
    1 row created.
    
    
    
    ALEN@PROD2> insert into prod(id,name,valid_start,valid_end) values(2,'Car',date'2020-01-01',date'2020-05-01');
    
    
    
    1 row created.
    
    
    
    ALEN@PROD2> insert into prod(id,name,valid_start,valid_end) values(3,'现金贷',date'2020-03-01',date'2020-11-01');
    
    
    
    1 row created.
    
    
    
    ALEN@PROD2> insert into prod(id,name,valid_start,valid_end) values(4,'消费贷',date'2019-03-01',null);
    
    
    
    1 row created.
    
    
    
    ALEN@PROD2> commit;
    
    
    
    Commit complete.

    5 查询数据

    ALEN@PROD2> select id,name,trunc(valid_start),trunc(valid_end) from prod;
    
    
    
    ID NAME TRUNC(VALID_START) TRUNC(VALID_END)
    
    ---------- -------------------- ------------------- -------------------
    
    1 Apple_01 2019-01-01 00:00:00 2019-10-31 00:00:00
    
    2 Car 2020-01-01 00:00:00 2020-05-01 00:00:00
    
    3 现金贷 2020-03-01 00:00:00 2020-11-01 00:00:00
    
    4 消费贷 2019-03-01 00:00:00

    6 检索数据

    6.1 普通查询方式

    SQL> select * from prod where date '2019-05-01' between valid_start and nvl(valid_end,sysdate);
    
    
    
    ID NAME
    
    ---------- --------------------
    
    1 Apple_01
    
    4 消费贷

    6.2 SELECT... AS OF方式

    ALEN@PROD2> select * from prod as of period for valid date'2020-03-01';
    
    
    
    ID NAME
    
    ---------- --------------------
    
    2 Car
    
    3 现金贷
    
    4 消费贷
    
    
    
    ALEN@PROD2> select * from prod as of period for valid date '2019-10-31';
    
    
    
    ID NAME
    
    ---------- --------------------
    
    4 消费贷

    6.2 SELECT... VERSIONS BETWEEN方式

    ALEN@PROD2> select * from prod versions period for valid between date '2020-03-01' and date '2020-05-01';
    
    
    
    ID NAME
    
    ---------- --------------------
    
    2 Car
    
    3 现金贷
    
    4 消费贷

    7 会话级别的可见性控制

    除了使用闪回查询、闪回版本查询数据之外,还可以通过dbms_flashback_archive的存储过程ENABLE_AT_VALID_TIME在会话级别指定表数据的可见性:显示所有数据(默认),显示指定时间的有效数据或者显示当前的有效数据。

    1)默认显示所有数据

    ALEN@PROD2> select * from prod;
    
    
    
    ID NAME
    
    ---------- --------------------
    
    1 Apple_01
    
    2 Car
    
    3 现金贷
    
    4 消费贷

    2)显示指定时间的数据

    ALEN@PROD2> exec dbms_flashback_archive.enable_at_valid_time('ASOF',date '2019-09-01');
    
    
    
    PL/SQL procedure successfully completed.
    
    
    
    ALEN@PROD2> select id,name from prod;
    
    
    
    ID NAME
    
    ---------- --------------------
    
    1 Apple_01
    
    4 消费贷

    3)显示当前时间可见的数据

    ALEN@PROD2> exec dbms_flashback_archive.enable_at_valid_time('CURRENT');
    
    
    
    PL/SQL procedure successfully completed.
    
    
    
    ALEN@PROD2> select id,name from prod;
    
    
    
    ID NAME
    
    ---------- --------------------
    
    3 现金贷
    
    4 消费贷

    4)显示所有数据

    ALEN@PROD2> exec dbms_flashback_archive.enable_at_valid_time('ALL');
    
    
    
    PL/SQL procedure successfully completed.
    
    ALEN@PROD2> select id,name from prod;
    
    
    
    ID NAME
    
    ---------- --------------------
    
    1 Apple_01
    
    2 Car
    
    3 现金贷
    
    4 消费贷

    以上就是Oracle 12c关于时间有效性的介绍,在使用时需要注意隐藏字段以及SQL中条件的正确判断。

  • 相关阅读:
    python 关于文件操作
    python2 编码与解码
    Git系列(二) 冲突解决
    异步回调机制分析
    CSS盒子模型理解
    Git多人协同开发模型
    CSS连载控制背景与CSS精灵
    函数调用在回调,委托与事件在程序设计中的应用
    TFS与Git结合进行代码管理
    Git系列之(二)Git协议与工作协同
  • 原文地址:https://www.cnblogs.com/alen-liu-sz/p/12975534.html
Copyright © 2020-2023  润新知