2015-02-09 69 views
0

我成功地执行该代码:触发在PL/SQL更新

CREATE or replace TRIGGER dept_no_exist 
BEFORE insert OR UPDATE on emp 
for each row 
DECLARE 
    x_count NUMBER; 
begin 
    select count(*) into x_count from dept where deptno=:new.deptno; 
    if(x_count=0) then 
      insert into dept values(:new.deptno,'A SAISIR','A SAISIR'); 
    end if; 
end; 
/

基本上就是我想要做的是正uplet(:new.deptno,'A SAISIR','A SAISIR')插入到表deptno当一个员工(表emp)受影响到部门中不存在的部门。我的触发器适用于插入查询,但不适用于更新查询。

+0

你在逻辑上是错误的,而更新'count(*)'不会是0.因此它不会'插入'在'dept'表 – Exhausted 2015-02-09 08:03:58

+0

好吧,但为什么它插入语句呢?因为我已经为这两个陈述写了“BEFORE” – Neo 2015-02-09 08:05:55

+0

@Exhausted - 为什么计算'dept'会受到针对'emp'的语句类型的影响? – 2015-02-09 08:06:50

回答

0

使用这样

CREATE or replace TRIGGER dept_no_exist 
AFTER insert OR UPDATE on emp 
for each row 
DECLARE 
    x_count NUMBER; 
begin 
    select count(*) into x_count from dept where deptno=:new.deptno; 
    if(x_count=0) then 
      insert into dept values(:new.deptno,'A SAISIR','A SAISIR'); 
    end if; 
end; 
/

行级触发器可以访问使用列的新的和现有的值:NEW.column名:OLD.column名参考,考虑到轴承以下限制。

  • 行级INSERT触发器:只有“:新作”引用尽可能 没有现有行。
  • 行级UPDATE触发器:“:NEW”和 “:OLD”引用都是可能的。 “:NEW”表示导致触发器触发的DML语句中显示的新值 。 “OLD”表示在应用更新 之前列中的现有值。
  • 行级DELETE触发器:只有“:OLD” 引用是可能的有在 触发语句提交没有新的数据,就在现有的行要被删除。

here:NEW值只在AFTER定时触发期间获得。

参考这里了解更多信息

http://oracle-base.com/articles/misc/database-triggers-overview.php

0

除非这仅仅是一个SQL过程的任务,我会强烈建议不要做你正在尝试做的。如果它是一个SQL课程的任务,他们正在教你可怕的概念。

您试图执行的是捕获员工数据的插入或更新。如果给定的部门编号与部门表中列出的任何部门不匹配,则需要创建具有该部门编号的部门。

绝对可怕,不好,非常糟糕的主意。在这种情况下,您想要插入或更新失败。您希望用户仔细地注视错误消息并说:“哇,我想我应该创建该部门,然后分配给员工。”

然而绝大多数时候他会这样说:“哎呀,那是17号部门,不是170号。”因此,当没有这样的部门时,您将在数据库中创建一个部门170。在这种情况下,设计良好的应用程序会询问用户是否想创建新部门。如果这是第一个被分配到新部门的员工,那么该部门将被创建并且分配可以继续。如果用户输入了错误的值,他有机会纠正并继续。

如果没有用户,如果这是从一些批处理源进入,您仍然不想创建新部门。在这种情况下,您可以将有问题的员工数据写出到日志表中以便稍后再有人检查。

您希望您的数据库尽可能简化用户的工作。你想让错误尽可能地变得困难。让虚假数据输入数据库更容易,这不是你应该努力的目标。