I'm trying to convert a sql server trigger which I have written. But I have been struggling with it a bit to convert it to oracle. I'm getting an error like Error at line: 26. Can anyone take a look at it? This would be a great help.
CREATE TRIGGER STAFF_ALLOCATION_LIMIT
ON Staff_Allocation
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @SID int
SELECT @SID = staff_Id FROM inserted
DECLARE @REC_COUNT int
DECLARE @ST_DATE DATE
DECLARE @END_DATE DATE
SELECT @END_DATE=staff_start_date FROM inserted
SELECT @ST_DATE=DATEADD(DAY, -(7), @END_DATE)
SELECT @REC_COUNT=COUNT(*)
FROM Staff_Allocation
WHERE staff_Id = @SID AND staff_start_date>@ST_DATE AND staff_end_date<@END_DATE
IF (@REC_COUNT >8 )
BEGIN
RAISERROR ('Only 8 schedules can be created for a staff per week',
16, 1)
ROLLBACK
END
END
In Oracle
CREATE OR REPLACE TRIGGER STAFF_ALLOCATION_LIMIT
AFTER INSERT OR UPDATE
ON Staff_Allocation
FOR EACH ROW
BEGIN
DECLARE
v_SID number(10)
v_SID = :NEW.staffId;
v_REC_COUNT number(10)
v_ST_DATE DATE
v_END_DATE DATE
SELECT staff_start_date INTO v_END_DATE FROM inserted
v_ST_DATE:=- * INTERVAL '1' DAY(5)(7) + v_END_DATE FROM dual
SELECT COUNT(*) INTO v_REC_COUNT
FROM Staff_Allocation
WHERE staff_Id = @SID AND staff_start_date>v_ST_DATE AND staff_end_date<v_END_DATE
IF (v_REC_COUNT >8 )
THEN
RAISERROR ('Only 8 schedules can be created for a staff per week',
16, 1)
ROLLBACK
END IF;
END
As I've already commented under the previous answer, an ordinary AFTER INSERT or UPDATE trigger will fail because the table is mutating. The savior might be the compound trigger (although there are other techniques one can use, but this one is rather simple).
Here's a demonstration based on Scott's EMP table - I don't want to allow more than 4 employees per department.
SQL> create or replace trigger trg_test
2 for update or insert on emp
3 compound trigger
4
5 type t_empcnt is record (deptno emp.deptno%type);
6 type r_empcnt is table of t_empcnt index by pls_integer;
7 g_empcnt r_empcnt;
8
9 after each row is
10 begin
11 g_empcnt(g_empcnt.count + 1).deptno := :new.deptno;
12 end after each row;
13
14 after statement is
15 l_cnt number;
16 begin
17 for i in 1 .. g_empcnt.count loop
18 select count(*) into l_cnt
19 from emp
20 where deptno = g_empcnt(i).deptno;
21
22 if l_cnt > 4 then
23 raise_application_error(-20000, 'Too many employees in department');
24 end if;
25 end loop;
26 end after statement;
27 end;
28 /
Trigger created.
Testing:
SQL> -- Number of employees per department:
SQL> select deptno, count(*) From emp group by deptno order by deptno;
DEPTNO COUNT(*)
---------- ----------
10 3
20 3
30 6
SQL> -- Inserting two new employees into the department 10 - one should pass, another fail:
SQL> insert into emp (deptno, empno, ename) values (10, 1, 'Little');
1 row created.
SQL> insert into emp (deptno, empno, ename) values (10, 2, 'Foot');
insert into emp (deptno, empno, ename) values (10, 2, 'Foot')
*
ERROR at line 1:
ORA-20000: Too many employees in department
ORA-06512: at "SCOTT.TRG_TEST", line 21
ORA-04088: error during execution of trigger 'SCOTT.TRG_TEST'
SQL>
I don't have your tables so I'm trying to create your trigger, but can't guarantee it'll actually work; if not, say so, we'll try to fix it.
create or replace trigger staff_allocation_limit
for update or insert on staff_allocation
compound trigger
type t_empcnt is record (sid staff_allocation.sid%type);
type r_empcnt is table of t_empcnt index by pls_integer;
g_empcnt r_empcnt;
after each row is
begin
g_empcnt(g_empcnt.count + 1).sid := :new.sid;
end after each row;
after statement is
l_cnt number;
begin
for i in 1 .. g_empcnt.count loop
select count(*) into l_cnt
from staff_allocation
where sid = g_empcnt(i).sid
and staff_start_date >= trunc(sysdate) - 8;
if l_cnt > 8 then
raise_application_error(-20000, 'Only 8 schedules can be created for a staff per week');
end if;
end loop;
end after statement;
end;
/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.