oracle DB中的自动增量备选方案

时间:2013-11-22 18:25:15

标签: sql database oracle database-design auto-increment

我对甲骨文来说相对较新,过去几个小时一直在浏览网页,但仍然无法找到一个对我这个问题的明确答案。

我来自软件工程背景,通过为每个表创建AI序列,我正在做的代码重复量令我感到沮丧。无论如何我可以定义一个AI函数,它接受序列和表的名称,所以我可以在触发器中调用函数,或者我是否需要对每个序列进行硬编码?

对于我拥有的12个表中的每一个,我目前都有这样的序列

CREATE OR REPLACE TRIGGER trg_site_addr
BEFORE INSERT OR UPDATE ON site_addr FOR EACH ROW
BEGIN 
IF INSERTING THEN
    IF :NEW.site_addr_id IS NULL THEN
        SELECT seq_site_addr_id.nextval
        INTO :NEW.site_addr_id
        FROM sys.dual;
    END IF;
END IF;
END;

理想情况下,我希望能够做到以下

CREATE OR REPLACE TRIGGER trg_site_addr
BEFORE INSERT OR UPDATE ON site_addr FOR EACH ROW
BEGIN 
IF INSERTING THEN
    IF :NEW.site_addr_id IS NULL THEN
        -- Param 1 = sequence name, Parm 2 = table name
        auto_increment(seq_site_addr_id, site_addr);
    END IF;
END IF;
END;

我将如何做到这一点,任何指针都将非常感激。

亚历。

*编辑* 为了消除任何困惑,我想创建一个函数,但我不知道是否可以在函数中嵌入一个序列然后使用这些参数,即

CREATE FUNCTION auto_increment( seq_name, table_col_id)
       SELECT seq_name.nextval
       INTO :NEW.table_col_id
       FROM sys.dual;
END;

这样它就会在每个表的触发器中动态创建增量序列,而不必在每个表上硬编码AI触发器。

如果这是不可能的话,那么对它进行硬编码并不是什么大不了的事,它只是我的一个查询。

2 个答案:

答案 0 :(得分:1)

我不推荐它,但是这样的事情应该或多或少地做你想做的事情:

CREATE FUNCTION auto_increment(seq_name in varchar2) RETURN NUMBER IS
  next_seq number;
BEGIN
   -- WARNING: use with care, possible SQL injections?
   execute immediate 'select ' || seq_name || '.nextval from dual' into next_seq;
   return next_seq
END auto_increment;

-- In trigger code
...
if inserting then
  if :new.id is null then
    :new.id := auto_increment('myseq');
  end if;
end if;
...

最好的方法是在INSERT语句中嵌入序列调用。如果INSERT语句无法修改,我只会使用触发器(可能它们是某些第三方软件的一部分,假设世界上每个数据库都支持自动增量列)。

答案 1 :(得分:1)

另一种方法是使用表来存储其他表ID 像:
identification holder

对于任何应用程序表(如客户表),我们需要做一些这样的事情:

insert into ID_Table (table_name, current_id) values ('CUSTOMER', 0);

获取新ID的功能是:

CREATE OR REPLACE FUNCTION fetch_new_id(p_table_name Varchar2) return number
IS
   result_value number;
BEGIN    
       SELECT ID_Tbale.current_id + 1
       INTO result_value 
       FROM ID_Table where trim(upper(ID_Table.table_name)) = trim(upper(p_table_name))
      for update;

      UPDATE ID_Tbale set current_id =  current_id + 1
      where trim(upper(ID_Table.table_name)) = trim(upper(p_table_name));

      COMMIT;

      RETURN result_value ;
      -- exception handling, etc
END;