1

当订单表出现时,我的任务是创建触发器以插入日志表

  1. 插入
  2. 更新

在星期五下午 5 点到星期一上午 9 点之间也将禁用插入/删除/更新。下面的解决方案涵盖了所有这些,但是因为它是一个前触发器,我不得不关闭完整性约束(这对日志表有影响吗?)

有没有人有任何建议我可以如何做到这一点并保持完整性约束(在 logono 列上)?

我正在考虑 11G 计算触发器,但在之前的答案中建议这不合适,加上向后兼容性的问题。

   CREATE OR REPLACE TRIGGER log_order
BEFORE INSERT OR UPDATE OR DELETE ON orders
FOR EACH ROW
DECLARE out_of_hours EXCEPTION;
BEGIN
IF INSERTING THEN
IF
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN 


    insert into order_log values
 (order_log_PK.nextval, 
 (select user from dual), 
 :NEW.ono, 
 (select  SYSDATE from dual), 
 'Order Inserted' ) ;
ELSE
    RAISE out_of_hours;
END IF;
END IF;
IF UPDATING THEN 
IF
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN 


    insert into order_log values
 (order_log_PK.nextval, 
 (select user from dual), 
 :NEW.ono, 
 (select  SYSDATE from dual), 
 'order updated' ) ;
ELSE
    RAISE out_of_hours;
END IF;
END IF;
IF DELETING THEN
IF 
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517
 THEN 
RAISE out_of_hourS;
END IF;
END IF;
EXCEPTION 
    WHEN out_of_hours THEN
    dbms_output.put_line('there is not privelages at this time');
    RAISE_APPLICATION_ERROR(-20001, 'CANNOT UPDATE OUT OF HOURS');
END;

谢谢

编辑

完整性问题的出现是因为进入日志表的 :NEW.ono 值尚未插入到订单表中,因为这是一个前触发器,因此违反了 logono 外键。

4

1 回答 1

2

您可以简化您的触发器,以便只检查周一上午 9 点到周五下午 5 点的条件一次,这样您就只有一个插入日志表的位置,并且无需额外的异常和异常处理程序。

您可以使触发器成为 AFTER INSERT 触发器,以便触发器在数据已经存在之后执行,ORDERS这样您就可以在其中创建ORDER_LOG引用ONO键 in的外键约束ORDERS。但是,想要创建这种约束似乎很奇怪。如果您将日志表创建为基表的子表,这意味着您将永远无法从 中删除一行ORDERS,因为总会有一个子行,或者您需要从 中删除所有行在执行ORDER_LOG删除ONO之前。这些通常都不是特别可取的——一般来说,拥有一个日志表的意义在于它将记录所有操作,而不仅仅是对基表中仍然存在的行的操作。

CREATE OR REPLACE TRIGGER log_order
  AFTER INSERT OR UPDATE OR DELETE ON orders
  FOR EACH ROW
DECLARE 
  l_operation varchar2(30);
BEGIN
  if to_number( to_char( sysdate, 'ddhh24' ) ) between 109 and 517
  then
    if inserting
    then
      l_operation := 'Order inserted';
    elsif updating
    then
      l_operation := 'Order updated';
    end if;

    -- Note that I'm guessing at the names of the columns in order_log
    insert into order_log( order_log_pk, 
                           modify_user,
                           ono,
                           modify_date,
                           description )
      values( order_log_PK.nextval,
              user,
              :new.ono,
              sysdate,
              l_operation );
  else 
    raise_application_error( -20001, 'Cannot update out of hours' );
  end if;
END;

虽然在INSERT不列出要插入的列的情况下对表执行操作在语法上可能是有效的,但这样做很危险。如果您将来添加另一列,即使不需要,您INSERT也将开始失败。如果您明确列出列,触发器将继续工作。如果您没有明确列出列,则相对难以发现将数据插入错误列的错误。我猜到了这些列是什么——你必须替换正确的列名。

于 2012-05-17T20:51:05.363 回答