【问题标题】:Create a table in Oracle using the boolean value (true) as an unique index field在 Oracle 中使用布尔值 (true) 作为唯一索引字段创建表
【发布时间】:2013-05-02 16:17:34
【问题描述】:

想象一个带有 KEY(Id_number, Begin_date, Service_Type)、End_date 和 Is_active 的表 CARD_SERVICE。

表 CARD_SERVICE 允许单个 Id_number 具有多个具有相同服务的寄存器,这是我不希望发生的。

我可以将表 CARD_SERVICE 更改为:KEY(Id_number, Service_Type),Begin_date, End_date 和 Is_active,现在每个 id_number 只能有一个服务类型,但是我无法保留之前在 Is_active 中设置为 False 的服务所以字段 is_active 失去了它的用途。

所以我想知道是否可以将布尔值设置为表中的唯一字段,以便创建一个仅在特定服务中没有活动服务时才接受新条目的表。

最好的问候

【问题讨论】:

  • 将 is_active 设置为 false 以何种方式使该字段无法使用?
  • 如果设置为 true,则表示服务处于活动状态,因此 id 无法再次添加相同的服务。如果 is_active 设置为 false 则意味着过期日期已过或有人停用 deactivate 服务,并且 id 可以再次添加此服务

标签: sql oracle database-design


【解决方案1】:

如果我按照您的要求进行操作,您可以使用基于函数的唯一索引来执行此操作:

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_numberservice_type 插入两条记录,同时将is_active 设置为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)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2020-07-29
    • 2015-08-07
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多