Нарушение первичного ключа для таблицы Oracle с временной достоверностью - PullRequest
1 голос
/ 13 июля 2020

Не могли бы вы поделиться со мной немного света относительно операции первичного ключа в таблице с временной достоверностью в 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", и мне нужно скопировать в TemporalTable_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: ограничение уникальности (TemporalTable_1) нарушено

Перед выполнением оператора вставки таблица была пустой. Итак, мой вопрос: почему мне не разрешено копировать строку в TemporalTable_1, даже если строки имеют другой valid_period.

Это потому, что Oracle на самом деле не заботился о столбце допустимого периода на первичном ключе?

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 13 июля 2020

Совершенно уверен, что временная валидность еще не оборудована для обработки первичных ключей и т.п.

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_PERIOD скрыт, что означает, что мы используем его для помощи в реализации преобразование запроса, необходимое для функции, а не для добавления первичных ключей.

1 голос
/ 13 июля 2020

Столбцы названия периода (VALID_PERIOD в вашем случае) содержат только идентификатор вашего периода. Проверьте этот сценарий и его вывод:

--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_PERIOD, как в вашем случае, и VT. Обратите внимание, что скрытые столбцы VALID_PERIOD и VT содержат только их ID. Они одинаковы для всех строк в таблице. Более того, в следующей презентации Филиппа Сальвисберга вы можете видеть, что Temporal Validity в Oracle еще не поддерживает временные ограничения целостности и, более того, он даже не поддерживает проверки на перекрывающиеся периоды. Так что вы пока не можете создавать такие ограничения. Но вы можете читать старые методы для таких вещей (например, такие как ограничения внешнего ключа START_DATE -> prev (END_DATE) и уникальное ограничение на ID, START_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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...