ユニークな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;