Postgres生成一个唯一的用户名

时间:2020-07-13 19:23:14

标签: sql postgresql stored-procedures

我有一个需要生成唯一用户名的要求。我知道我将如何在服务器端执行此操作,但希望使其尽可能高效并作为过程的一部分在数据库上执行,但由于我不太常使用SQL,所以不确定从哪里开始。

我希望能够使用其姓氏的首字母和姓氏以及一些数字来创建用户名,如果用户已经存在该用户名,则可以用1更新它。例如

我有用户

  • 鲍勃·琼斯bjones1
  • 比尔·琼斯bjones2

如果添加了用户Beatrice Jones,则将为bjones3。

但是用户可以选择选择用户名,以便有人可能已经选择了bjones3,因此我希望它自动生成bjones4。

如果没有用户B Jones,则创建的第一个用户名应为bjones

理想情况下,所有这一切都将在用户插入数据库的过程中发生,因此我的Go代码只需执行一个数据库调用就可以插入用户。

更新:

当用户选择自己的用户名时,我会检查用户名是否存在,并阻止他们使用该用户名。

3 个答案:

答案 0 :(得分:1)

嗯。 。 。我认为这可以做到:

select 'bjones' || coalesce(lpad( ((regexp_match(max(username), '[0-9]+$'))[1]::int + 1)::text, 5, '0'), '00000')
from t
where username ~ '^bjones[0-9]{5}$';

Here是db <>小提琴。

答案 1 :(得分:1)

更加严格和参数化,具有4位序号。

with 
unp as -- user name prefix
(select left(lower(:givenname), 1) || lower(:surname) unp),
maxno as -- max existing seq.number for this username prefix
(
    select coalesce(max((regexp_match(username, '(\d+)$'))[1]::integer), 0) maxno 
    from usernames
    where username ~ ('^'||(select unp from unp)||'\d+$')
)   
select (select unp from unp) || to_char((select maxno + 1 from maxno), 'FM0009')  username;

答案 2 :(得分:0)

我用以下代码做了类似的事情:

_username = left(lower(_firstname), 1) || lower(_lastname);
PERFORM id FROM users WHERE username = _username;
IF FOUND THEN
  FOR i in 1 .. 999
  LOOP
    _username := _username || i;
    PERFORM id FROM users WHERE username = _username;
    IF NOT FOUND THEN
      EXIT;
    END IF;
  END LOOP;
END IF;