我是否需要为这样一个简单的约束编写触发器?

时间:2011-01-05 23:45:19

标签: oracle10g constraints

我真的很难知道我的问题的标题中会包含哪些单词,因为我不确定是否存在与我的问题相关的数据库模式。我将尽可能地简化问题,直接解决问题的核心。

假设我有一些表格。 第一个是窗口小部件类型列表:

create table widget_types (
    widget_type_id number(7,0) primary key,
    description varchar2(50)
);

下一个包含图标:

create table icons (
    icon_id number(7,0) primary key,
    picture blob
);

即使用户可以选择他们喜欢的小部件,也可以为每个小部件类型选择一个预定义的小部件子集。

create table icon_associations (
    widget_type_id number(7,0) references widget_types,
    icon_id number(7,0) references icons,
    primary key (widget_type_id, icon_id)
);

create table icon_prefs (
    user_id number(7,0) references users,
    widget_type_id number(7,0),
    icon_id number(7,0),
    primary key (user_id, widget_type_id),
    foreign key (widget_type_id, icon_id) references icon_associations
);

到目前为止非常简单。

现在让我们假设如果我们向未设置其偏好的用户显示图标,我们选择与当前小部件相关联的适当图像之一。我想指定在这种情况下显示的首选图标,这是我遇到问题的地方:

alter table icon_associations 
    add ( is_preferred char(1) check( is_preferred in ('y','n') ) )
;

我看不出如何强制执行每个widget_type,只有一行,而且is_preferred设置为'y'。

我知道在MySQL中,我能够在检查约束中编写子查询以快速解决此问题。 Oracle无法做到这一点。

我的错误是此列在icon_associations表中没有业务?如果不是它应该去哪里?这种情况是,在Oracle中,约束只能通过触发器来处理吗?

我的问题只是因为我想尽可能去约束路线。

非常感谢你的帮助, 保罗

2 个答案:

答案 0 :(得分:0)

我认为解决您问题的一种简单方法是使用另一个名为

的表
icon_default_associations (widget_type_id, icon_id)

并简单地使(widget_type_id, icon_id)服从UNIQUE约束(或使其成为主键)。

如果您按照尝试的方式进行操作,我认为您正在超载icon_associations的目的。

答案 1 :(得分:0)

如果默认图标没有更改,您是否可以确保默认图标首先进入icon_associations表?

这样,您总是可以保证只有一个默认图标,只要有ARE图标,它就永远不会消失,而且您不需要使用is_preferred列或其约束和触发器。

检索默认图标也很容易:

SELECT * from icon_associations WHERE ID=MIN(ID)

缺点是更改默认图标需要一些工作,但如果这种情况永远不会发生,这将解决您的is_preferred列问题。