使用Recurrsion编辑pseudo_encrypt PostgreSQL函数以避免某些ID

时间:2015-06-09 07:49:00

标签: postgresql recursion

因为我无法通过数十亿个表插入来轻松测试,所以我想帮助找出如何使用pseudo_encrypt(https://wiki.postgresql.org/wiki/Pseudo_encrypt)函数来处理已经有顺序id的表id他们。例如,我们的用户表有大约10,000个用户。 Ids从1..10,000开始。

现在我想使用pseudo_encrypt函数来获取10,001 ID,它看起来像这样:1064621387932509969

问题在于"随机"伪加密返回值可能会与我的早期1-10,000个用户ID一起发生冲突。

我不想更改前10,000个用户ID,因为这会给当前用户带来一些痛苦(必须重新登录,网址损坏等)。

我的想法是使用某种递归函数来处理这个......就像这样的工作,还是我的使命?

CREATE OR REPLACE FUNCTION "pseudo_encrypt"("VALUE" int) RETURNS int     IMMUTABLE STRICT AS $function_pseudo_encrypt$
DECLARE
l1 int;
l2 int;
r1 int;
r2 int;

return_value int;

i int:=0;
BEGIN
    l1:= ("VALUE" >> 16) & 65535;
    r1:= "VALUE" & 65535;
    WHILE i < 3 LOOP
        l2 := r1;
        r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
        r1 := l2;
        l1 := r2;
        i := i + 1;
END LOOP;

return_value = ((l1::int << 16) + r1); // NEW CODE

// NEW CODE - RECURSIVELY LOOP UNTIL VALUE OVER 10,000
WHILE return_value <= 10000
    return_value = pseudo_encrypt(nextval('SEQUENCE_NAME'))
END LOOP

RETURN return_value;
END;

$function_pseudo_encrypt$ LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:0)

好评!这似乎可以完成这项工作:

CREATE OR REPLACE FUNCTION get_next_user_id() returns int AS $$
DECLARE
return_value int:=0;
BEGIN
    WHILE return_value  < 10000 LOOP
        return_value  := pseudo_encrypt(nextval('test_id_seq')::int);
    END LOOP;
    RETURN return_value ;
END;
$$ LANGUAGE plpgsql strict immutable;