【问题标题】:raise_application error not working in oracle 11graise_application 错误在 oracle 11g 中不起作用
【发布时间】:2022-01-16 17:22:12
【问题描述】:

我已经尝试 PL/SQL 很长一段时间了,我已经尝试创建一个过程和一个触发器,但我无法获得所需的输出。让我分享一下我到目前为止所做的事情。

==> create or replace procedure cast(act_id movie_cast.act_id%TYPE, mov_id movie_cast.mov_id%TYPE, role movie_cast.role%TYPE)
        IS
        begin
        insert into movie_cast values(act_id, mov_id, role);
        end;
        /
        
        Procedure created.
        
==>> SQL> create or replace trigger trg1
          2  before insert on movie_cast
          3  for each row
          4  declare
          5  num number;
          6  begin
          7  select count(act_id) into num from movie_cast where mov_id = :new.mov_id;
          8  if(:old.mov_id = :new.mov_id AND :old.act_id = :new.act_id) then
          9  raise_application_error(-20001, 'Actor already in the movie!');
         10  end if;
         11  end;
         12  /
        
        Trigger created.

我已经自定义了第 9 行中的错误,但我没有在那里得到错误。就像当我满足这个条件==> if(:old.mov_id = :new.mov_id AND :old.act_id = :new.act_id) 时,我想要一个错误但我没有得到它。 有人可以帮我吗? 非常感谢!

SQL> select * from movie_cast;

ACT_ID     MOV_ID ROLE

   101        901 John Scottie Ferguson
   102        902 Miss Giddens
   103        903 T. E. Lawrence
   104        904 Michael
   105        905 Antonio Salieri
   106        906 Rick Deckard
   107        907 Alice Harford
   108        908 McManus
   109        909 J. J. Gittes
   110        910 Eddie Adams
   111        911 Alvy Singer
   112        912 San
   113        913 Adny Dufresne
   114        914 Lester Burnham
   115        915 Rose DeWitt Bukater
   116        916 Sean Maguire
   117        917 Ed
   118        918 Renton
   119        919 Alfred Borden
   120        920 Elizabeth Darko
   121        921 Older Jamal
   122        922 Ripley
   114        923 Bobby Darin
   122        922 dummy

已选择 24 行。

PS:这是movie_cast表,我想在其中插入act_id和mov_id,触发条件是你不能为同一部电影投两次,但你可以为不同的电影投一个演员。

【问题讨论】:

  • 我真的不知道你想在这里做什么,但不会引发这个异常,因为当你插入数据时,没有 :old 行值。您正在插入这一行,并且您在插入触发器之前。 :old 值可以在例如:更新触发器之前使用,但确保不在插入触发器之前。即使它编译,你也会有空值。您正在对要插入行的表进行计数 - 很可能会导致通过变异表错误发出信号的问题。更何况,你甚至没有在任何地方进一步使用这个计数,你为什么这样做呢?
  • 你能看一下吗,这次我更新了问题以更清晰?

标签: sql oracle plsql triggers procedure


【解决方案1】:

这是一个错误的方法。

movie_cast 上从同一个表中选择的行级触发器将引发变异表错误。

正确的做法是在这些列上创建唯一索引(或唯一/主键约束),例如

create unique index on movie_cast (mov_id, act_id);

【讨论】:

  • 你能看看这个问题吗?我已经更新了。
  • 恐怕我的回答没有任何变化。它是您需要的唯一索引。
  • SQL> 在 movie_cast(act_id, mov_id) 上创建唯一索引 ind1;在movie_cast(act_id,mov_id)上创建唯一索引ind1 *第1行错误:ORA-01452:无法创建唯一索引;发现重复键
  • act_id中已经有重复值了!第114章 重复了……
  • ... 这意味着您首先必须对其进行排序(删除重复项),然后创建唯一索引。
【解决方案2】:

回答您的问题-:旧值在触发之前为空,这就是为什么您的条件永远不会被满足,永远不会-即使您插入带有空值的行,null=null 条件也不会通过,null 是 null 是 TRUE,但是null = null 会给你 FALSE,至少对于 Oracle DB。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-10
    • 2013-10-07
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    相关资源
    最近更新 更多