Sql 在Oracle中使用布尔值(true)作为唯一索引字段创建表

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将失去其使用 因此,我想知道是否可以将布

设想一个具有密钥(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可以再次添加此服务