如果我跟着你想要什麼,你可以使用一個獨特的基於函數的索引要做到這一點:
create table card_service (
id_number number, begin_date date, service_type number, end_date date,
is_active varchar2(5),
constraint ck_is_active check (is_active in ('TRUE', 'FALSE'))
);
Table created.
create unique index ui_card_service on card_service (
case when is_active = 'TRUE' then id_number else null end,
case when is_active = 'TRUE' then service_type else null end
);
Index created.
NULL值不包含在索引中,所以您將只有TRUE
記錄的索引「條目」,並將case
語句應用於這兩個字段意味着結果在這兩列中仍然是唯一的。
試圖與is_active
組插入兩個記錄相同id_number
和service_type
,既TRUE
,失敗:
insert into card_service values (1, date '2013-01-01', 1, null, 'TRUE');
1 row created.
insert into card_service values (1, date '2013-01-02', 1, null, 'TRUE');
insert into card_service values (1, date '2013-01-02', 1, null, 'TRUE')
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.UI_CARD_SERVICE) violated
更新現有記錄到FALSE
第一允許新TRUE
要被添加;
update card_service set is_active = 'FALSE'
where id_number = 1 and service_type = 1 and is_active = 'TRUE';
1 row updated.
insert into card_service values (1, date '2013-01-02', 1, null, 'TRUE');
1 row created.
而且你可以繼續這樣做:
insert into card_service values (1, date '2013-01-04', 2, null, 'TRUE');
insert into card_service values (2, date '2013-01-05', 1, null, 'TRUE');
insert into card_service values (2, date '2013-01-06', 2, null, 'TRUE');
所以你最終獲得:
select * from card_service;
ID_NUMBER BEGIN_DAT SERVICE_TYPE END_DATE IS_AC
---------- --------- ------------ --------- -----
1 01-JAN-13 1 FALSE
1 02-JAN-13 1 FALSE
1 03-JAN-13 1 TRUE
1 04-JAN-13 2 TRUE
2 05-JAN-13 1 TRUE
2 06-JAN-13 2 TRUE
update card_service set is_active = 'FALSE'
where id_number = 1 and service_type = 1 and is_active = 'TRUE';
1 row updated.
insert into card_service values (1, date '2013-01-03', 1, null, 'TRUE');
1 row created.
您可以爲其他組合添加TRUE
記錄這將是莫儘管保持一個單獨的歷史表(大概是舊的),但是你的主表只有當前記錄(不論是TRUE
還是FALSE
)。
以什麼方式將is_active設置爲false會使字段不可用? – 2013-05-02 16:36:13
如果它設置爲true,這意味着服務處於活動狀態,因此ID不能再次添加相同的服務。如果is_active設置爲false,則意味着過期日期到期或有人停用了de服務,並且該id可以再次添加此服務 – Winter 2013-05-02 17:00:47