使用随机代码更新多行中的列

时间:2017-12-15 13:19:46

标签: postgresql

您好我正在尝试为我的数据库中的每个用户生成唯一代码。 代码是他们的名字的第一个字母,姓氏的第一个字母,' - ',6个字符长度的随机字符串,以及当前年份的最后两个数字的组合。

这是我的代码:

UPDATE user_info SET code = (SELECT UPPER(substring(first_name FROM 1 FOR 1))
             || UPPER(substring(last_name FROM 1 FOR 1))
       || '-'
         || (SELECT UPPER(array_to_string(array((
   SELECT SUBSTRING('abcdefghjklmnpqrstuvwxyz23456789'
                    FROM mod(FLOOR(random()*32)::int, 32)+1 FOR 1)
   FROM generate_series(1,6))),'')))
             || '-'
       || to_char(CURRENT_DATE, 'YY'))
WHERE user_id IN (SELECT user_id FROM user_info);

然而,这适用于每个列重复应该是随机字符串的中间部分。

2 个答案:

答案 0 :(得分:1)

子选择仅评估一次。

尝试使用VOLATILE这样的函数:

CREATE OR REPLACE FUNCTION rand(integer) RETURNS text
   LANGUAGE sql VOLATILE STRICT AS
$$SELECT string_agg(
            substring('ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
                      FROM (random() * 32 + 0.5)::integer
                      FOR 1),
            ''
         )
FROM generate_series(1, $1)$$;

然后使用

UPDATE user_info
SET code = upper(substring(first_name FROM 1 FOR 1)) ||
           upper(substring(last_name FROM 1 FOR 1)) ||
           '-' || rand(6) || '-' ||
           to_char(CURRENT_DATE, 'YY')
WHERE user_id IS NOT NULL;

奇怪的WHERE条件是对您奇怪的WHERE条件的优化(也许您根本不需要它)。

答案 1 :(得分:1)

使用函数会允许这样做,所以:

create or replace function randomids(first text, last text) returns text as $$
   begin
   return (select upper(substring(first from 1 for 1))
   || upper(substring(last from 1 for 1))
   || '-'
   || (select upper(array_to_string(array((
       select substring('abcdefghijklmnopqrstuvwxyz23456789'
       from mod(floor(random()*32)::int, 32)+1 for 1)
       from generate_series(1,6))),'')))
   || '-'
   || to_char(current_date, 'YY'));
   end;
   $$ language plpgsql;

然后您可以使用以下功能进行更新:

update user_info uo set code = (
   select randomids(ui.first_name, ui.last_name)
   from user_info as ui
   where ui.user_id = uo.user_id)
   where uo.user_id in (select user_id from user_info);