ユニークなIDを生成する話なんですが、連番で生成すると会員数というか規模がばれてしまいます。
普通は乱数を生成したり、シーケンス番号からHash値を求めたりしてると思いますが、今回はOracleを使ったランダムシーケンサーを実装してみたいと思います。今回はその準備編ということで必要な関数を作ってみました。
作ったと言っても、DBMS_RANDOMパッケージの実装の拡張です。大小英数と数字バージョンが無かったので。
後は重複チェックが必要です。
重複チェックをするにはテーブルが必要になるわけですが、実際に主キーとして使っているテーブルを捜査するのか、それとも専用のテーブルを用意するのかが悩みどころです。今回は専用のテーブルを用意する予定です。
重複チェックもする関数を作ったら完成ですが、それは次回ということで。
CREATE OR REPLACE FUNCTION random_string (opt char, len NUMBER) RETURN VARCHAR2 PARALLEL_ENABLE is optx char (1) := lower(opt); rng NUMBER; n BINARY_INTEGER; ccs VARCHAR2 (128); xstr VARCHAR2 (4000) := NULL; BEGIN IF optx = 'z' THEN ccs := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ; rng := 62; ELSIF optx = 'u' THEN ccs := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; rng := 26; ELSIF optx = 'l' THEN ccs := 'abcdefghijklmnopqrstuvwxyz'; rng := 26; ELSIF optx = 'a' THEN ccs := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; rng := 52; ELSIF optx = 'x' THEN ccs := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; rng := 36; ELSIF optx = 'p' THEN ccs := ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' ; rng := 95; ELSE ccs := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; rng := 26; END IF; FOR i IN 1 .. least(len,4000) LOOP n := TRUNC(rng * DBMS_RANDOM.value) + 1; xstr := xstr || SUBSTR(ccs,n,1); END LOOP; RETURN xstr; END random_string;