簡體   English   中英

如何在 pl/sql 中解決此觸發器?

[英]How do i resolve this trigger in pl/sql?

我想要一個觸發器,讓不超過 3 名員工在一個給定的項目上工作,這是我擁有的代碼,但不能很好地工作,有時工作,有時不工作。

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 表中的所有內容:

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'));

有兩個問題。

問題 1:我猜您希望觸發器在 count(codi_proj) 大於 3 時觸發。當您插入第 4 條記錄時,觸發器不會觸發,因為觸發器在“插入前”觸發,這意味着它被計為 3並且不會考慮插入當前記錄。因此,要修復它,您可以修改觸發器以執行大於或等於contador >= 3的代碼將完美運行。

問題2:測試方法還有另一個問題。如果您通過將記錄插入到項目中來測試觸發器,如帖子中所述,您必須在每次插入(或DML)操作后提交。觸發器與任何其他數據庫一樣 object從持久化的 state 數據中讀取。

至少使用當前的行級觸發器方法,您不會做您想做的事情。 原因是行級觸發器無法訪問導致它觸發的表 因此,語句“select... from empleats... 將引發異常”ORA-04091:表正在變異,觸發器/函數可能看不到它”,因為觸發器是為了響應針對表 empleats 的 DML 而觸發的。更好的流程是在業務規則層,甚至是應用程序級別進行此檢查。但是,如果您堅持使用觸發器,則可以通過after 語句觸發器來完成。該觸發器確實必須(或至少應該)處理多個項目超過最大員工限制的可能性。所以(見小提琴):

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;

感謝您的幫助,我已經部分解決了這個問題。 但是,當我插入它時,它可以工作,但是當我更新它時,當我在同一個項目中有超過 3 個工作人員時,它就不起作用了。 我認為它不起作用,因為升級需要一個運行另一個程序的程序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM