具有时间有效性的oracle表的sql主键冲突

byqmnocz  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(379)

你能告诉我一些关于在oracle中主键操作在表上的时间有效性吗?
我创建了一个具有以下模式的表

Create table TemporalTable_1 (
    Customer_ID number(8),
    Customer_name varchar2(100),
    valid_period_start timestamp, 
    valid_period_end timestamp, 
    period for valid_period(valid_period_start, valid_period_end),
    constraint TemporalTable_1_PK primary key (Customer_ID , VALID_PERIOD)
)

我有来自另一个表“othertable”的以下记录,我需要复制到临时表\u 1中

Customer_ID       | Customer_name        | Valid_period_start      | Valid_Period_end
------------------+----------------------+-------------------------+-----------------------
00001             | John Chan            | 01 JUN 2020 00:00:00    | 09 JUN 2020 23:59:59
00001             | Johnny Chan          | 10 JUN 2020 00:00:00    | Null

以下是我的剧本:

insert into TemporalTable_1 select * from OtherTable;

ora-00001:违反了唯一约束(临时表1)
在执行insert语句之前,表是空的。所以我的问题是为什么不允许我将行复制到临时表1中,即使行的有效期不同。
是因为oracle实际上不关心主键上的validperiod列吗?
提前谢谢!

0kjbasz6

0kjbasz61#

period name(在您的例子中是有效的\u period)列只包含您的period的id。检查此脚本及其“输出:

--drop table TemporalTable purge;
-- formatting for sqlplus:
col periodname for a20;
col constraint_name for a20;
col search_condition_vc for a80;
col valid_period_start for a16;
col valid_period_end   for a16;
col PERIODSTART for a20;
col PERIODEND   for a20;
alter session set nls_timestamp_format='yyyy-mm-dd hh24:mi';
-- end of formatting

Create table TemporalTable (
    Customer_ID number(8),
    Customer_name varchar2(10)
);

alter table TemporalTable add (
    valid_period_start timestamp, 
    valid_period_end   timestamp,
    period for valid_period(valid_period_start, valid_period_end)
);

ALTER TABLE TemporalTable ADD (
    vt_start DATE,
    vt_end DATE,
    PERIOD FOR vt (vt_start, vt_end)
);
-- inserting overlapping records:
insert into TemporalTable
select 1, 'A' , date'2020-01-01', date'2020-01-10', date'2020-01-01', date'2020-01-10' from dual union all
select 1, 'B' , date'2020-01-05', date'2020-01-08', date'2020-01-01', date'2020-01-10' from dual
/
commit;
-- check valid_period and vt hidden columns:
select tt.*,valid_period,vt from TemporalTable tt
/
select * 
from TemporalTable 
       AS OF PERIOD FOR valid_period DATE '2020-01-06'
/
select 
 constraint_name,
 constraint_type,
 search_condition_vc
from user_constraints c 
where table_name='TEMPORALTABLE';

select * from sys.SYS_FBA_PERIOD 
where obj#=(select object_id from user_objects where object_name='TEMPORALTABLE');

如您所见,我添加了2个有效期:valid\u period(如您的案例)和vt。请注意,隐藏列valid\u period和vt只包含它们的id。它们对于表中的所有行都是相同的。此外,在下面philippsalvisberg的演示中,您可以看到oracle中的时间有效性还不支持时间完整性约束,而且它甚至不支持对重叠周期的检查。所以还不能创建这样的约束。但您可以阅读这些内容的旧方法(例如,像外键约束start\u date->prev(end\u date)和id上的唯一约束start\u date)
输出:

CUSTOMER_ID CUSTOMER_N VALID_PERIOD_STA VALID_PERIOD_END VT_START            VT_END              VALID_PERIOD         VT
----------- ---------- ---------------- ---------------- ------------------- ------------------- ------------ ----------
          1 A          2020-01-01 00:00 2020-01-10 00:00 2020-01-01 00:00:00 2020-01-10 00:00:00    726847999  726848005
          1 B          2020-01-05 00:00 2020-01-08 00:00 2020-01-01 00:00:00 2020-01-10 00:00:00    726847999  726848005

CUSTOMER_ID CUSTOMER_N VALID_PERIOD_STA VALID_PERIOD_END VT_START            VT_END
----------- ---------- ---------------- ---------------- ------------------- -------------------
          1 A          2020-01-01 00:00 2020-01-10 00:00 2020-01-01 00:00:00 2020-01-10 00:00:00
          1 B          2020-01-05 00:00 2020-01-08 00:00 2020-01-01 00:00:00 2020-01-10 00:00:00

CONSTRAINT_NAME      C SEARCH_CONDITION_VC
-------------------- - --------------------------------------------------------------------------------
VALID_PERIOD52D1FF   C (VALID_PERIOD_START < VALID_PERIOD_END) and (VALID_PERIOD > 0)
VT52D205             C (VT_START < VT_END) and (VT > 0)

      OBJ# PERIODNAME                FLAGS PERIODSTART          PERIODEND                 SPARE
---------- -------------------- ---------- -------------------- -------------------- ----------
     89220 VALID_PERIOD                  0 VALID_PERIOD_START   VALID_PERIOD_END
     89220 VT                            0 VT_START             VT_END

https://www.doag.org/formes/pubfiles/5217205/2013-dev-philipp_salvisberg-multi-temporal_database_features_in_oracle_12c-praesentation.pdf

irtuqstp

irtuqstp2#

可以肯定的是,暂时有效性还没有装备好,以本机处理主键等。

SQL> Create table TemporalTable_1 (
  2      Customer_ID number(8),
  3      Customer_name varchar2(100),
  4      valid_period_start timestamp,
  5      valid_period_end timestamp,
  6      period for valid_period(valid_period_start, valid_period_end),
  7      constraint TemporalTable_1_PK primary key (Customer_ID , VALID_PERIOD)
  8  );

Table created.

SQL> select column_name, hidden_column
  2  from   user_tab_cols
  3  where  table_name = 'TEMPORALTABLE_1'
  4  order by column_id;

COLUMN_NAME                    HID
------------------------------ ---
CUSTOMER_ID                    NO
CUSTOMER_NAME                  NO
VALID_PERIOD_START             NO
VALID_PERIOD_END               NO
VALID_PERIOD                   YES

valid\u period列是隐藏的,这意味着我们使用它来帮助实现特性所需的查询转换,而不是在其上添加主键。

相关问题