首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ORA-04091:表JOSEP.EMP正在发生变化,触发器/函数可能看不到它

ORA-04091:表JOSEP.EMP正在发生变化,触发器/函数可能看不到它
EN

Stack Overflow用户
提问于 2019-04-12 03:17:59
回答 1查看 85关注 0票数 0

"ORA-04091:表JOSEP.EMP正在发生变化,触发器/函数可能看不到它“

我必须显示一条消息,其中包含旧的和新的薪水,以及受雇人员的代码(emp_no),但我不能这样做。

代码语言:javascript
复制
create or replace trigger emp_AU 
after update of salario 
on emp for each row
    declare
    v_emp_no emp.emp_no%type;  
    begin
    select emp_no into v_emp_no FROM emp;
    insert into auditaemple VALUES ((select count(*) from auditaemple)+1, 'El salario del empleado '||v_emp_no||'antes era de '||:old.salario||' y ahora será '||:new.salario, sysdate);
    end emp_AU;

这样做会产生"ORA-04091:“错误。如果我删除v_emp_no,我将不会得到消息,但我需要显示受雇人员的代码。我做错了什么。

提前感谢。

EN

回答 1

Stack Overflow用户

发布于 2019-04-12 03:54:14

导致变化表错误的原因是,当表处于事务中间时,从表中选择数据-您正在更新它,同时-从它进行选择。因为您不能这样做(好吧,您可以这样做,有解决方法,但您不应该这样做),Oracle不允许您这样做。

不需要选择伪记录;您已经有了它-使用:new伪记录引用它。此外,按照您的方式,您会得到TOO-MANY-ROWS错误,因为没有WHERE子句将结果集限制为一行。

不要使用count + 1 (也不要使用max + 1或类似的“技术”),特别是当您要填充一个应该是唯一的列时。只要它能在单用户环境中工作,它迟早会在多用户环境中失败。使用序列(或者,如果您的数据库支持序列,则使用标识列)。

这里有一个有效的例子来说明你是如何做到这一点的。

首先,测试用例:

代码语言:javascript
复制
SQL> create table temp as select empno emp_no, sal salario
  2                       from emp where deptno = 10;

Table created.

SQL> create table auditaemple (id number, text varchar2(100), datum date);

Table created.

SQL> create sequence seqa;

Sequence created.

触发器:

代码语言:javascript
复制
SQL> create or replace trigger trg_bu_emp
  2    before update of salario on temp
  3    for each row
  4  begin
  5    insert into auditaemple (id, text, datum)
  6      values (seqa.nextval,
  7              'El salario del empleado '||:new.emp_no||' antes era de '||
  8               :old.salario||' y ahora será '||:new.salario, sysdate);
  9  end;
 10  /

Trigger created.

测试:

代码语言:javascript
复制
SQL> select * from temp;

    EMP_NO    SALARIO
---------- ----------
      7782       2450
      7839       5000
      7934       1300

SQL> update temp set salario = 9000 where emp_no = 7839;

1 row updated.

SQL> select * From auditaemple;

        ID TEXT                                     DATUM
---------- ---------------------------------------- ----------------
         1 El salario del empleado 7839 antes era d 11.04.2019 21:47
           e 5000 y ahora será 9000


SQL>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55639707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档