2011-04-08 80 views
1

我有两个表如下:冲突触发器

  • department(alpha, college, etc.)
  • course(id, alpha, college, title, etc.)

学院和α都存在通过设计两个表英寸我决定取消一些标准化因为大学和阿尔法在观看课程时总是需要。

我有一个触发该department表更新后,以便更新在course表中的所有行与新alphacollege值执行。我也有更新course表,以确保在alpha之前执行触发器 - college对用户在他或她的编辑提交的department表存在;如果这对不在那里,会引发和应用程序错误。

这些触发冲突。第二个检查department表的新值是否在其中,但它们尚未如此,因此它应该失败。

是否有可能,如果是第一次执行的第一个触发器忽略第二触发?我真的不想在这种情况下执行第二个触发器,因为我知道这些值在第一个表中。如果这是不可能的,有没有更好的方式来做到这一点,而不改变我的模式?

回答

3

你的第二个触发听起来没有什么比一个外键更变量的值的第二触发。取而代之的是在course上创建外键约束。这在我的测试中起作用。

然而,似乎是不必要的工作来支持提供很少好处的非规范化。如果您只想编写简单的查询,请创建一个视图来加入这两个表并在查询中使用它。如果您担心连接性能,我非常怀疑这会是一个问题,除非您在表上缺少明显的索引。

+0

我想我可能会这样做。我通常不是DBA,但他被公共汽车撞到了。 – geowa4 2011-04-08 17:05:22

2

我会真诚地建议删除你的触发方式都在一起,因为它是通过负担脏读。每当遇到像这样的挑战时,我只会使用存储过程来实现DML。如果正确实施,您可以轻松获得触发器的所有优点。

如果你怕是要确保部门表中的所有更新按照你的逻辑,做过程变化,删除更新权限的任何用户,除了存储过程的所有者。这确保了唯一可以修改该表的调用者是您控制和理解的存储过程。巧合的是,它成为更新表格的唯一方法。

只需$ 0.02

+0

我想这样做,如果没有其他方式。我只是不想再做任何存储过程。 :-P – geowa4 2011-04-08 00:40:55

+1

这是一个很好的建议,但是编写存储过程不能替代声明适当的完整性约束 - 在这种情况下,从外部到外部的外键。约束将有助于确保您的代码是正确的。 – 2011-04-08 13:20:27

+0

优秀点Dave =)+1给你 – Pepto 2011-04-08 20:22:13

2

像使用触发器来实现其他大多数情况下,你可以看到这里的负担,因为数据模型本身有缺陷。

您可以实现相同的逻辑如下,保持使用PK和FK约束的所有规则。

---Department references College... 

Create table department(
    department_id number primary key, 
    aplha varchar2(20) not null, 
    college varchar2(20) not null 
); 

***--Course belongs to a department.. so should be a child of department. 
--If it's possible for different depts to give the same course (IT and CS), 
--you'll have 
--a dept_course_asc table*** 

Create table Course(
    course_id number primary key 
    department_id number references department(department_id), 
    course_name varchar2(100) not null 
); 

如果您有学生表,您可以将其与另一个student_table关联表关联起来。

可能会出现这些数据表比您显然多得多,但是如果您希望避免数据冗余并且不希望在父表中更改父表时更新所有表中的列,以上型号是唯一的选择。

+0

alpha是部门。您已将数据添加到此问题。你的大学表是完全没用的。 – geowa4 2011-04-08 16:44:43

+0

您添加的唯一好处(一旦我拿走了您添加的数据)就是fk。但是,就像我在问题中所说的那样,我通过将部门中的一个字段复制到课程来避免单个字段的联合,从而将其解除规范化。如果你争辩说我应该每次都加入,那就说出来。 – geowa4 2011-04-08 16:57:56

+0

够公平的。我同意我根据以前见过的其他问题添加数据,但我无法真正理解“alpha”意味着“部门”。现在修改帖子。是的,我相信你应该根据伪造关键部门ID加入两张表格,而不是阿尔法和大学。 – 2011-04-08 17:43:11

0

有对问题有两种可能的解决方案。

解决方案1:使用DEFERRABLE FK约束。

此解决方案仅适用于(alpha,college)组合是唯一的并且可以定义为部门表的PK。 在这种情况下,您不需要课程表上的触发器。

相反,您定义了一个DEFERRABLE FK(alpha,college)当然是引用了部门表。

而在更新部门之前,您必须执行SET CONSTRAINT ... DEFERRED语句see documentation。 然后FK将不会被验证,直到提交。

解决方案2:使用系统上下文

您关掉使用本地system_context第二触发。

必须先创建上下文。 see User Created Contexts

部门触发器将上下文中的变量设置为某个值。

并在课程,你检查的背景下