Вам нужно извлечь только числовую часть идентификатора, которую вы можете сделать с помощью
regexp_substr(userid, '[0-9]*$')
, а затем преобразовать ее в число, прежде чем найти максимум (в противном случае вы все равно будете выполнять сравнение строки сортировка от 9 до 10):
max(to_number(regexp_substr(userid, '[0-9]*$')))
и вы, вероятно, захотите, чтобы корень идентификатора, который вы проверяете, вообще не существовал, что вы можете сделать с помощью nvl()
или coalesce()
:
select coalesce(max(to_number(regexp_substr(userid, '[0-9]*$'))), 0) as max_num
from pv_users
where regexp_like(userid, '^'|| 'TomKelly'|| '[0-9]*');
MAX_NUM
----------
13
select coalesce(max(to_number(regexp_substr(userid, '[0-9]*$'))), 0) as max_num
from pv_users
where regexp_like(userid, '^'|| 'PJames'|| '[0-9]*');
MAX_NUM
----------
12
select coalesce(max(to_number(regexp_substr(userid, '[0-9]*$'))), 0) as max_num
from pv_users
where regexp_like(userid, '^'|| 'NewName'|| '[0-9]*');
MAX_NUM
----------
0
... а затем добавьте 1 и добавьте обратно в корень, чтобы получить следующий идентификатор.
В зависимости от ваших бизнес-правил, вы можете захотетьчтобы сделать фильтр нечувствительным к регистру.
Вы должны знать, что два сеанса, выполняющие эту операцию одновременно, будут видеть один и тот же результат, поэтому оба будут пытаться создать один и тот же идентификатор, например TomKelly14
.Вам нужно либо сериализовать эту операцию генерации, либо включить откат, например, проверку на наличие нарушения PK при попытке вставить новое значение в таблицу и повторение, если это произойдет.