将SQL Server触发器转换为Oracle

时间:2018-04-04 16:05:53

标签: sql oracle

我正在尝试转换我编写的sql server触发器。但我一直在努力将它转换为oracle。我收到错误的错误:26。有人可以看一下吗?这将是一个很大的帮助。

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

在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

1 个答案:

答案 0 :(得分:0)

正如我在前面的回答中已经评论过的那样,普通的AFTER INSERT或UPDATE触发器会因为表变异而失败。救世主可能是复合触发器(虽然可以使用其他技术,但这个很简单)。

这是基于Scott的EMP表的演示 - 我不希望每个部门允许超过4名员工。

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.

测试:

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>

我没有你的桌子,所以我试图创建你的触发器,但不能保证它实际上会工作;如果不是这样,我们会尝试解决它。​​

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;
/