【问题标题】:Oracle trigger invalidOracle 触发器无效
【发布时间】:2012-07-19 20:49:42
【问题描述】:

我是 SQL 新手,我正在尝试创建一个可以插入审计表的触发器。

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
end;

错误:

Warning: execution completed with warning
trigger late_ship_insert Compiled.

但是一旦我尝试插入语句,它就会告诉我触发器没有工作它来删除它。

Error starting at line 1 in command:
insert into suborder 
    values  ( 8, 3, '10-jun-2012', '12-jul-2012', 'CVS', 3) 
Error at Command Line:1 Column:12
Error report:
SQL Error: ORA-04098: trigger 'COMPANY.LATE_SHIP_INSERT' is invalid and failed re-validation
04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger.
*Action:   Options are to resolve the compilation/authorization errors,
           disable the trigger, or drop the trigger.

任何想法是什么导致了这个,任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 创建触发器后执行SHOW ERRORS 并向我们显示错误消息。
  • 我会惊讶地发现 int 在 Oracle 中输入...试试数字?
  • 我认为您缺少END IF; 加号,我认为所有declared 变量都应该放在开头。
  • 一旦我创建了触发器,:Warning: 执行完成,警告触发器late_ship_insert 已编译。我将 int 更改为 number 但仍然相同。问题是当我在子订单上尝试插入语句时,它给了我帖子上的第二个错误
  • @user1354275 - 假设您使用的是 SQL*Plus,当您创建触发器并收到警告时,请键入 show errors。正如@a_horse_with_no_name 所说,这将向您显示您在尝试创建触发器时遇到的实际错误和警告。

标签: database oracle triggers plsql


【解决方案1】:

格式化代码时明显的错误是您的IF 语句缺少END IF

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
  end if;
end;

一般来说,您应该始终在您的INSERT 语句中列出目标表的列,而不是依赖于您的INSERT 语句为每一列指定一个值并以正确的顺序指定它们的事实。这将使您的代码更加健壮,因为例如当有人向表中添加其他列时它不会变得无效。看起来像这样(我猜ship_audit 表中的列名)

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit( emp_id, order_no, suborder_no, req_ship_date, actual_ship_date )
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
  end if;
end;

【讨论】:

  • 我明白了,非常感谢你的解释,它真的很有帮助!
猜你喜欢
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2020-04-04
  • 2013-02-09
相关资源
最近更新 更多