oracle应用程序中的plsql代码中的序列生成器

时间:2018-05-29 11:32:02

标签: oracle plsql

我有一个样本表,如下所示

PO_HEADER ||    ITEM   || LINE_NUM

   1              X 
   1              Y 
   1              Z 
   1              A 
   1              B 

我想更新line_num列中的序列号,例如1 ... 5。 ,当我输入另一行时,下一个序列号应该像line_number列中的6那样自动生成。

我想编写代码来更新line_num中的序列号,&还要捕获下一个序列号。因此,当我输入新行时,我应该得到下一个序列号

3 个答案:

答案 0 :(得分:0)

演示:http://sqlfiddle.com/#!4/4d6ff/1

CREATE TABLE Table1
    ("PO_HEADER" int, "ITEM" varchar2(1), "LINE_NUM" int)
;

INSERT ALL 
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'X', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'Y', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'Z', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'A', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'B', NULL)
SELECT * FROM dual
;

create sequence alamakota;

现在:

update table1 set LINE_NUM = alamakota.nextval;

select * from table1;

| PO_HEADER | ITEM | LINE_NUM |
|-----------|------|----------|
|         1 |    X |        1 |
|         1 |    Y |        2 |
|         1 |    Z |        3 |
|         1 |    A |        4 |
|         1 |    B |        5 |

答案 1 :(得分:0)

人们通常使用一个序列(Oracle对象)来提供唯一性,但(一般来说)并非无间隙。序列易于实现;您可以在插入期间调用它,也可以创建一个数据库触发器,将列值设置为下一个序列号。

如果您坚持使用“MAX + 1”选项,请注意它在多用户环境中即将失败 - 两个或更多用户获取相同的MAX值,具体取决于COMMIT时刻和列唯一性(主要/唯一密钥,唯一索引)第一个将成功,其他人的插入将失败。

有一种解决方法 - 通过自治事务功能维护序列号的附加表。

如果您使用12c,请使用标识列。否则,我会建议一个序列。

答案 2 :(得分:0)

我不会为此使用序列。

如果有一个父表,PO_HEADER是外键,请在父行上获取一个锁。然后,SELECT MAX(line_num)+1...为该PO并使用它。在将插入提交到TABLE1之前,不要释放父表上的锁。

如果您没有父表,则可以使用DBMS_LOCK来完成同样的事情。 (分配代表PO的用户锁并将其锁定以代替父表。)

由于您的应用程序设计良好且所有 TABLE1插入都通过此代码发生,因此您知道它可以正常工作。父表上的锁定确保两个会话不会获得相同的下一个行号,因为锁会强制它们一个接一个地执行操作。

如果您的应用程序设计不是很好,这对您没有帮助。