我正在尝试查看是否存在用分区逻辑创建序列的东西。 我需要一个依赖于其他主键ex的序列号:
id_person sequence id
1 | 1
1 | 2
2 | 1
3 | 1
1 | 3
因此序列必须依赖于id_person
分区。在oracle上是否有这样的东西,或者我必须自己在应用程序级别实现它?
您已经创建了这个PLSQL包的一个功能和过程:
PROCEDURE INIT_SEQUENCE(NAME varchar2, pkColumnNameList PARTITIONED_SEQUENCE_PK_COLUMN);
FUNCTION GET_NEXT_SEQUENCE_VALUE(NAME varchar2, pkPartitionColValue PARTITIONED_SEQUENCE_COL_VALUE) RETURN NUMBER;
INIT_SEQUENCE - 输入要在序列中关联的名称和列名称列表,这些列名称是固定的主键部分,用于对序列进行vincolate Ex:'ID_PERSON'
此过程的工作是创建将根据pkColumnNameList列管理序列增量的表。
GET_NEXT_SEQUENCE_VALUE-获取要递增的序列名称和pkColumnNameList主键的值,然后执行下一步: 1)动态创建sql工作 2)dbms_lock.allocate_unique();锁定桌子 3)检查表中是否存在输入中pk值的记录 4)如果存在记录,则在序列列中使用max + 1更新记录 5)如果没有记录,则在序列列中插入带有1的新记录 6)返回新的id;
我想提前收到有关此事的评论......
答案 0 :(得分:4)
次要序列是否无间隙的实际要求是什么?如果是这样,你就会遇到巨大的序列化/可扩展性问题。
如果您需要提供一个供人类消费的无间隙序列,您可以使用实际序列(或时间戳,就此而言),如Nick Pierpont建议并保留可扩展性,您可以使用分析函数。
数据集(t1):
ID_PERSON SEQUENCE_ID
---------- -----------
1 1
2 2
3 3
1 4
1 5
1 6
2 7
3 8
1 9
SQL:
select *
from
(select id_person,
sequence_id as orig_sequence_id,
rank ()
over (partition by id_person
order by sequence_id)
as new_sequence_id
from t1
)
order by id_person, new_sequence_id;
结果:
ID_PERSON ORIG_SEQUENCE_ID NEW_SEQUENCE_ID
---------- ---------------- ---------------
1 1 1
1 4 2
1 5 3
1 6 4
1 9 5
2 2 1
2 7 2
3 3 1
3 8 2
答案 1 :(得分:0)
我担心你必须这样做:
INSERT INTO t
(
id_person,
sequence_id
)
VALUES
(
<your_person_id>,
( SELECT 1 + NVL( MAX( sequence_id ), 0 )
FROM t
WHERE t.id_person = <your_person_id>
)
)
答案 2 :(得分:0)
您正在寻找的不是sequence,正如Oracle文档所声称的那样:“序列生成器提供一系列连续的数字”。
您正在寻找一个取决于另一个的计算字段,在这种情况下是主键。正如其他人建议您需要在代码中添加逻辑。这意味着在procedure
或insert
句中。