指定されたプレフィックスの最大値を検索してインクリメントできます。
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
。これには従来のシーケンスよりも多くの作業が伴いますが、少なくとも挿入が相互に待機することはありません (デッドロックにつながる可能性があります)。