Oracle中不使用触发器的自动增量

Oracle中不使用触发器的自动增量,oracle,triggers,auto-increment,sequences,Oracle,Triggers,Auto Increment,Sequences,除了使用触发器之外,在oracle中实现自动增量的其他方法有哪些?您可以创建和使用oracle序列。语法和详细信息见 也读了这篇文章 要了解其他RDBMS中有关自动编号的限制,我记得在Oracle时代,如果不使用触发器,您无法实现自动递增列。任何生成自动递增列的解决方案都涉及触发器和序列(我假设您已经知道这一点,因此没有触发器注释)。如果您不需要序列号,而只需要唯一的ID,则可以使用默认的SYS\u GUID()。即: 从序列中获取下一个值的触发器是实现等同于自动增量的最常见方法: creat

除了使用触发器之外,在oracle中实现自动增量的其他方法有哪些?

您可以创建和使用oracle序列。语法和详细信息见

也读了这篇文章
要了解其他RDBMS中有关自动编号的限制,我记得在Oracle时代,如果不使用触发器,您无法实现自动递增列。任何生成自动递增列的解决方案都涉及触发器和序列(我假设您已经知道这一点,因此没有触发器注释)。

如果您不需要序列号,而只需要唯一的ID,则可以使用默认的SYS\u GUID()。即:


从序列中获取下一个值的触发器是实现等同于自动增量的最常见方法:

create trigger mytable_trg
before insert on mytable
for each row
when (new.id is null)
begin
    select myseq.nextval into :new.id from dual;
end;
如果控制插入,则不需要触发器-只需在insert语句中使用序列:

insert into mytable (id, data) values (myseq.nextval, 'x');
这可以隐藏在API包中,以便调用方不需要引用序列:

mytable_pkg.insert_row (p_data => 'x');
create sequence seq;
但是使用触发器更“透明”。

创建一个序列:

mytable_pkg.insert_row (p_data => 'x');
create sequence seq;
然后添加一个值

insert into table (id, other1, other2)
values (seq.nextval, 'hello', 'world');

注意:除了FerranB的答案之外,有关序列(起始值、增量等)的更多选项,请查看oracle文档。

或许值得一提的是,与MySQL中自动激励的工作方式相反:
  • 序列在数据库范围内工作,因此它们可以用于多个表,并且值对于整个数据库是唯一的
  • 因此:截断表不会重置“自动增量”功能。如果您真的不想使用“基于触发器”的解决方案,可以通过编程方法实现自动增量功能,使用
    getGeneratedKeys()
    方法获取自动增量键的值

    以下是一段代码片段供您参考:

    Statement stmt = null;
    ResultSet rs = null;
    
    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                    java.sql.ResultSet.CONCUR_UPDATABLE);
    
    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTable");
    
    stmt.executeUpdate("CREATE TABLE autoIncTable ("
                    + "priKey INT NOT NULL AUTO_INCREMENT, "
                    + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
    
    stmt.executeUpdate("INSERT INTO autoIncTable  (dataField) "
                    + "values ('data field value')",
                    Statement.RETURN_GENERATED_KEYS);
    
    int autoIncKeyFromApi = -1;
    
    rs = stmt.getGeneratedKeys();
    
    if (rs.next()) {
        autoIncKeyFromApi = rs.getInt(1);
    }
    else {
        // do stuff here        
    }
    
    rs.close();
    
    来源:

    从12c开始,您可以使用,这使得表和自动增量之间的链接明确;不需要触发器或序列。语法是:

    create table <table_name> ( <column_name> generated as identity );
    
    创建表(作为标识生成);
    
    只有当:new.id为NULL时,触发器才可能生成序列值,这将更接近于其他数据库品牌中的自动递增。请注意,每行需要一个值,否则:new不可访问。。。或者至少当我在PL/SQL中上课时,我的课本上是这么说的。相关问题:是否可以创建一个序列,然后将nextval方法设置为默认值?i、 e.创建序列序号;创建表foo(mycol编号默认值seq.nextval);完全明白。缓存和回滚使这几乎不可能+1.我认为它不是真正的并发友好“我认为它不是真正的并发友好”我支持。我见过以这种方式编写的web应用程序可以做各种有趣的事情……这真是最糟糕的做法。永远不要使用这些东西。如果桌子空了怎么办-(如果桌子满了怎么办?)(当然可以。您创建了一个Insert过程来获取nextval。您可以撤销该表上的Insert,并授予该进程/包上的execute。不需要触发。为什么选择这个答案?因为它是真的。如果不使用触发器和序列,则无法执行普通插入并实现与自动增量相同的效果。Mark Brady的回答也是正确的,如果你把存储的PROC看作是一个普通的插入。