您可以搜索指定前缀的最大值并将其递增:
SQL> WITH DATA AS (
2 SELECT '00010001' id FROM DUAL UNION ALL
3 SELECT '00010002' id FROM DUAL UNION ALL
4 SELECT '00010003' id FROM DUAL UNION ALL
5 SELECT '00080001' id FROM DUAL
6 )
7 SELECT :prefix || to_char(MAX(to_number(substr(id, 5)))+1, 'fm0000') nextval
8 FROM DATA
9 WHERE ID LIKE :prefix || '%';
NEXTVAL
---------
00010004
我相信您知道这是一种低效的生成主键的方法。此外,它不会在多用户环境中很好地发挥作用,因此无法扩展。并发插入将等待然后失败,因为列上有一个 UNIQUE 约束。
如果前缀总是相同的长度,您可以在一定程度上减少工作量:您可以创建一个专门的索引,以最少的步数找到最大值:
CREATE INDEX ix_fetch_max ON your_table (substr(id, 1, 4),
substr(id, 5) DESC);
然后以下查询可以使用该索引,并将在检索到的第一行处停止:
SELECT id
FROM (SELECT substr(id, 1, 4) || substr(id, 5) id
FROM your_table
WHERE substr(id, 1, 4) = :prefix
ORDER BY substr(id, 5) DESC)
WHERE rownum = 1
如果您需要使用相同的前缀同时插入,我建议您使用DBMS_LOCK
请求锁定指定的newID
. 如果由于有人已经在插入此值而导致调用失败,请尝试使用newID+1
. 尽管这比传统序列涉及更多的工作,但至少您的插入不会相互等待(可能导致死锁)。