Sql 在Oracle中使用布尔值(true)作为唯一索引字段创建表
设想一个具有密钥(Id号、开始日期、服务类型)、结束日期且处于活动状态的桌卡服务 table CARD_服务允许一个Id_号码具有多个寄存器,具有相同的服务,这是我不希望发生的 我可以将表卡\u服务更改为:KEY(Id\u编号、服务\u类型)、Begin\u date、End\u date和Is\u active,现在每个Id\u编号只能有一个单一的服务类型,但是我无法保留在Is\u active中设置为False的先前服务,因此字段Is\u active将失去其使用 因此,我想知道是否可以将布尔值设置为表中的唯一字段,以便创建仅在特定服务中没有活动服务时才接受新条目的表Sql 在Oracle中使用布尔值(true)作为唯一索引字段创建表,sql,oracle,database-design,Sql,Oracle,Database Design,设想一个具有密钥(Id号、开始日期、服务类型)、结束日期且处于活动状态的桌卡服务 table CARD_服务允许一个Id_号码具有多个寄存器,具有相同的服务,这是我不希望发生的 我可以将表卡\u服务更改为:KEY(Id\u编号、服务\u类型)、Begin\u date、End\u date和Is\u active,现在每个Id\u编号只能有一个单一的服务类型,但是我无法保留在Is\u active中设置为False的先前服务,因此字段Is\u active将失去其使用 因此,我想知道是否可以将布
致以最诚挚的问候如果我正在关注您想要的内容,您可以使用一个唯一的基于函数的索引来执行此操作:
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.
索引中不包括空值,因此您将只为TRUE
记录提供索引“条目”,并且对这两个字段应用case
语句意味着结果在这两列上仍然是唯一的
尝试为相同的id\u编号
和service\u类型
插入两条记录时,如果均处于活动状态
设置为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.
你可以继续这样做:
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
记录:
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
不过,将一个单独的历史记录表和(可能是旧的)记录放在一起会更正常,所以主表只有当前记录(无论是
TRUE
还是FALSE
).设置为“活动”以何种方式使字段不可用?如果设置为“真”,则表示服务处于活动状态,因此id无法再次添加相同的服务。如果is_active设置为false,则表示过期日期已过期或有人停用了服务,id可以再次添加此服务