【问题标题】:Column values as factorial in Oracle SQL列值作为 Oracle SQL 中的阶乘
【发布时间】:2015-03-18 18:16:59
【问题描述】:

我创建了一个触发器,它会根据顺序在每次插入新记录时自动增加 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...

【问题讨论】:

  • 那么你必须在其他地方做一个阶乘函数。然后将序列的值传递给这个函数,返回的值将被分配到newid var中,然后插入到表中。
  • 您需要删除BEFORE 触发器并将AFTER 触发器(使用阶乘函数)更改为BEFORE 触发器。这样做:AFTER 触发器中的select fac(test_seq.nextval) into :new.tab_id from dual; 实际上并没有为新插入的列设置值。

标签: sql oracle triggers sequence factorial


【解决方案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;
/

【讨论】:

  • 为什么 tab_ 为空?
  • 因为需要计算一次
  • 没有充分的理由从同一个表上的触发器更新表。
  • 没错,没有充分的理由这样做。但是,当您使用AFTER 触发器时会发生这种情况,而BEFORE 触发器更合适。
【解决方案2】:

From Oracle's documentation. 您想在这种情况下使用BEFORE 触发器,AFTER 触发器实际上不会仅仅通过在NEW 中设置它来更改表的数据:

由于触发器使用了 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;
/

【讨论】:

    猜你喜欢
    • 2022-09-26
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 2011-10-14
    • 1970-01-01
    相关资源
    最近更新 更多