2017-12-15 6 views
1

こんにちは私のデータベースの各ユーザーに固有のコードを生成しようとしています。 コードは、ファーストネームの最初の文字、姓の最初の文字、 ' - '、6文字の長さのランダムな文字列、および現在の年の最後の2桁の組み合わせです。複数行の列をランダムなコードで更新する

これは私のコードです:

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); 

しかし、これは列ごとに繰り返されますランダムな文字列であると考えられる中央部に動作します。

+0

あなたの目標は、ユーザーごとに固有のコードを作成する場合は、私がお勧めします代わりにシーケンスを使用します。すべてのユーザーが乱数、日付、および名前に頼るのではなく、一意の識別子を持つことを確実に知っている方がよいでしょう。私は確率が*信じられないほど*低いことを知っています、現在の方法では、コードの重複がありますが、シーケンスで99.9%〜100%を変更しないのはなぜですか?または、より詳細には、より詳細な日付を追加することもできます(たとえば、20171215082612)。 –

+0

お時間をいただきありがとうございます。残念ながら、この形式でコードを生成する必要があります。 – user3718908

答えて

1

副選択は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)$$; 

次に、(多分あなたがすべてでそれを必要としない奇妙なWHERE条件があなたの奇妙なWHERE条件の最適化である

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; 

を使用)。機能を使用して

+0

ありがとうございました。 – user3718908

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); 
関連する問題