Postgres - 声明时的返回函数

时间:2015-04-07 06:52:55

标签: postgresql function random

嘿我想创建一个随机数。当这个随机数已经存在时,我想一次又一次地调用randomnumber函数。在这种情况下,我需要在CASE WHEN语句中返回randomnumber函数。 这是行不通的。仍然得到该数字已存在的错误。我想为唯一列创建一个随机数:

CREATE OR REPLACE FUNCTION getrandomnumber(integer, integer)
        RETURNS integer AS
        $BODY$
        DECLARE
            start_int ALIAS FOR $1;
            end_int ALIAS FOR $2;
            name int;
        BEGIN
        name = trunc(random() * (end_int-start_int) + start_int);

        CASE WHEN (select count(alias) from drivers where alias = name limit 1) = 0

        THEN RETURN name;

        ELSE RETURN getrandomnumber(start_int, end_int);

        END CASE;
        END;

        $BODY$

        LANGUAGE plpgsql VOLATILE STRICT
        COST 100;
        ALTER FUNCTION getrandomnumber(integer, integer)
        OWNER TO postgres;

1 个答案:

答案 0 :(得分:0)

在没有并发运行时,即一次只有一个用户运行时,您的函数可以正常工作。

使用:

CREATE TABLE drivers (alias integer);

INSERT INTO drivers(alias) VALUES (1),(2);

CREATE OR REPLACE FUNCTION ...;

然后

INSERT INTO drivers(alias) VALUES (getrandomnumber(1, 5));

工作两次,然后无限递归失败。


如果多个会话同时调用您的函数,则该函数将无法正常工作。您必须LOCK TABLE drivers IN EXCLUSIVE MODE或准备好处理唯一的违规错误。

我认为你真正想要的东西更像是一个不重复的“随机序列”,例如: the pseudo-encrypt function


顺便说一句,同时:

(select count(alias) from drivers where alias = name limit 1) = 0

会起作用,你应该尝试:

exists (select 1 from drivers where alias = name limit 1)

因为它通常更快。