我有一个样本表,如下所示
PO_HEADER || ITEM || LINE_NUM
1 X
1 Y
1 Z
1 A
1 B
我想更新line_num列中的序列号,例如1 ... 5。 ,当我输入另一行时,下一个序列号应该像line_number列中的6那样自动生成。
我想编写代码来更新line_num中的序列号,&还要捕获下一个序列号。因此,当我输入新行时,我应该得到下一个序列号
答案 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
插入都通过此代码发生,因此您知道它可以正常工作。父表上的锁定确保两个会话不会获得相同的下一个行号,因为锁会强制它们一个接一个地执行操作。
如果您的应用程序设计不是很好,这对您没有帮助。