列值作为Oracle SQL中的阶乘

时间:2015-01-20 13:36:03

标签: sql oracle triggers sequence factorial

我创建了一个触发器,每次插入新记录时,都会根据序列自动增加id。像这样:

create sequence test_seq 
start with 1 
increment by 1 
nomaxvalue; 

--drop trigger test_trigger;
create or replace trigger test_trigger
before insert on myTable
for each row
begin
select test_seq.nextval into :new.tab_id from dual;
end;

但是,我想插入行索引的阶乘。我怎么能实现这个目标?

编辑:

create or replace trigger test_trigger
after insert on myT
for each row
begin
select fac(test_seq.nextval) into :new.tab_id from dual;
end;

添加了fac功能,工作正常:

create or replace function fac(n in number)

return number

is
     v number :=1;
begin
     for i in  1..n
loop
     v :=v * i;
end loop;
     return v;

端;

但我仍然只看到表中的1,2,3,4而不是1,2,6,24 ......

2 个答案:

答案 0 :(得分:0)

From Oracle's documentation.您希望在此实例中使用BEFORE触发器,AFTER触发器实际上不会更改表的数据,只需在NEW中设置它:< / p>

  

因为触发器使用BEFORE关键字,所以它可以访问新的   它们进入表之前的值,并且可以更改值   通过分配到:NEW.column_name。

,可以轻松纠正错误

我的猜测是,您仍然会看到序列中的旧值,因为您的BEFORE触发器仍然存在; AFTER触发器不会更改这些值。

所以你想要的是以下内容:

CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT ON myt
FOR EACH ROW
BEGIN
    SELECT FAC(test_seq.nextval) INTO :new.tab_id FROM dual;
END;
/

我认为从Oracle 11g开始(或者可能是10g;不记得了)你也可以做以下事情:

CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT ON myt
FOR EACH ROW
BEGIN
    :new.tab_id := FAC(test_seq.nextval);
END;
/

答案 1 :(得分:-1)

执行类似

的操作
create function factorial (n integer) return integer as
  ...

create or replace trigger test_trigger
 after insert on mytable
 -- don't do this for each row
begin
  update mytable set 
    tab_id = factorial((select count(*) from mytable))
  where tab_id is null;
end;
/