首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在pl/sql中解析此触发器?

如何在pl/sql中解析此触发器?
EN

Stack Overflow用户
提问于 2020-05-05 11:20:27
回答 3查看 63关注 0票数 0

我希望有一个触发器,使不超过3名员工在一个给定的项目中工作--这是我拥有的代码,但不能很好地工作,有时工作,有时不工作。

代码语言:javascript
复制
create or replace trigger t_maxim_empleats_projecte
before insert or update of codi_proj
on empleats
for each row
declare
contador number(5);
begin
select count(codi_proj) into contador from empleats where codi_proj= :new.codi_proj;
if contador > 3 then
RAISE_APPLICATION_ERROR(-20000, 'No poden haver-hi més de 3 empleats en un
mateix projecte.');
end if;
end;

这是我在SQL表中拥有的全部内容:

代码语言:javascript
复制
create table Projectes(
    codi_proj   number(5), 
    nom_proj    varchar2(25),
    pressupost  number(10,2),
    primary key (codi_proj)
);

create table Empleats(
    codi_emp    number(5),
    nom_emp varchar2(15),
    sou     number(10,2),
    codi_dept   number(5),
    codi_proj   number(5),
    data_alta   date,
    primary key (codi_emp),
        foreign key (codi_dept)   references Departaments(codi_dept) on delete set null,
        foreign key (codi_proj)   references Projectes(codi_proj) on delete set null
);

insert into projectes(codi_proj, nom_proj, pressupost)
values (1, 'Daisy', 240000);

insert into projectes(codi_proj, nom_proj, pressupost)
values (2, 'CLAM', 63000);

insert into projectes(codi_proj, nom_proj, pressupost)
values (3, 'Vocal Processor', 600000);

insert into empleats(codi_emp, nom_emp, sou, codi_dept, codi_proj,data_alta)
values (1, 'Maria', 21000, 1, 1,TO_DATE('10/10/1980','dd/mm/yyyy'));

insert into empleats(codi_emp, nom_emp, sou, codi_dept, codi_proj,data_alta)
values (2, 'Josep', 18000, 1, 1,TO_DATE('01/08/1982','dd/mm/yyyy'));

insert into empleats(codi_emp, nom_emp, sou, codi_dept, codi_proj,data_alta)
values (3, 'Ramon', 48000, 4, 2,TO_DATE('05/04/2005','dd/mm/yyyy'));
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-05-05 21:24:13

至少用当前的行级触发器方法,您不会做您想做的事情。原因是行级触发器无法访问导致其触发的表。因此,语句"select . from empleats.将抛出异常"ORA-04091: table正在发生变异,触发器/函数可能看不到它“,因为触发器是响应DML而针对表执行的。一个更好的过程是在业务规则层,甚至在应用程序级别进行此检查。但是,如果您坚持要触发器,则可以通过后置语句触发器来完成它。该触发器必须(或至少应该)处理多个可能超过最大员工限制的项目。所以(请参阅小提琴):

代码语言:javascript
复制
create or replace trigger limit_3_emp_per_proj_ais
           after insert on employees 
declare
   k_new_msg_line    constant            varchar2(3)  := chr(10) || '  ';
   k_max_emp_message constant            varchar2(80) := 
       'No rows inserted!' || k_new_msg_line || 'Following Projects have exceed max of 3 employees:'; 
   cursor proj_over_3_emp is
         select proj.name, proj.proj_id, count(*)
           from projects  proj 
           join employees emp
             on (emp.proj_id = proj.proj_id)
          group by proj.proj_id, proj.name    
         having count(*) > 3 
          order by proj.proj_id;

   l_proj_exceeds_3_emp                varchar2(3500) := null;           
begin 
   for proj_emp in proj_over_3_emp  
   loop 
       l_proj_exceeds_3_emp := l_proj_exceeds_3_emp || k_new_msg_line ||
                               proj_emp.name || '(' || proj_emp.proj_id || ')';
   end loop; 

   if l_proj_exceeds_3_emp is not null
   then 
      raise_application_error( -20199,k_max_emp_message || l_proj_exceeds_3_emp);
   end if;

end limit_3_emp_per_proj_ais;
票数 0
EN

Stack Overflow用户

发布于 2020-05-05 12:41:38

有两个问题。

问题1:当count(codi_proj)大于3时,我猜您预期触发器会触发。当您插入第4条记录时,触发器不会在“插入前”触发触发器,这意味着触发器将被计数为3,并且不会认为当前记录是inserted.So来修复它,您可以修改触发器以执行大于或等于contador >= 3的操作,代码将完美地工作。

问题2: testing.If的方法还有另一个问题,您正在测试触发器,将记录插入到项目中,如post中所述,您必须在每次插入(或DML)operation.Trigger之后提交,就像从数据的持久化状态读取任何其他数据库对象一样。

票数 0
EN

Stack Overflow用户

发布于 2020-05-05 20:34:22

感谢你的帮助,我已经部分地解决了这个问题。但是,当我插入它时,它可以工作,但是当我更新它时,当我在同一个项目中有超过3个工作人员时,它就不能工作了。我认为它不起作用,因为uptade需要运行另一个过程的过程

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

https://stackoverflow.com/questions/61611922

复制
相关文章

相似问题

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