PostgreSQL:修改存储过程参数

3

我有一个数据库表格,游戏玩家可以在其中互相评价并留下可选的评论(如果他们自己的“声誉”足够好):

create table pref_rep (
        id varchar(32) references pref_users(id) check (id <> author),
        author varchar(32) references pref_users(id),
        author_ip inet,
        good boolean,
        fair boolean,
        nice boolean,
        about varchar(256),
        last_rated timestamp default current_timestamp
);

一个玩家的“声誉”是所有“公平”和“友好”值的总和。

我正在尝试修改我的PL/pgSQL过程,以创建这样的评级,使得“关于”评论只能由“声誉”>=30的用户创建,并且“好的”,“公平的”和“友好的”值仅能由“声誉”>0的用户设置:

create or replace function pref_update_rep(_id varchar,
        _author varchar, _author_ip inet,
        _good boolean, _fair boolean, _nice boolean,
        _about varchar) returns void as $BODY$
        declare
        rep integer;
        begin

        select
        count(nullif(fair, false)) +
        count(nullif(nice, false)) -
        count(nullif(fair, true)) -
        count(nullif(nice, true))
        into rep from pref_rep where id=_author;

        if (rep <= 0) then
                return;
        end if;

        if (rep < 30) then
                _about := null;
        end if;

        delete from pref_rep
        where id = _id and
        age(last_rated) < interval '1 hour' and
        (author_ip & '255.255.255.0'::inet) =
        (_author_ip & '255.255.255.0'::inet);

        update pref_rep set
            author    = _author,
            author_ip = _author_ip,
            good      = _good,
            fair      = _fair,
            nice      = _nice,
            about     = _about,
            last_rated = current_timestamp
        where id = _id and author = _author;

        if not found then
                insert into pref_rep(id, author, author_ip, good, fair, nice, about)
                values (_id, _author, _author_ip, _good, _fair, _nice, _about);
        end if;
        end;
$BODY$ language plpgsql;

很抱歉,我遇到了以下错误:
ERROR:  "$7" is declared CONSTANT
CONTEXT:  compilation of PL/pgSQL function "pref_update_rep" near line 21

这意味着上面的_about := null;赋值会失败。
有没有什么好方法可以让它起作用,或者我必须在这里引入一个临时变量?
使用PostgreSQL 8.4.7和CentOS Linux 5.5。
谢谢! Alex

我不太擅长SQL,你的意思是什么?该ID引用另一个表 - pref_users,在那里该ID是主键。 - Alexander Farber
我认为Catcall的意思是pref_rep没有主键或者在id上没有索引。对参考列进行索引是个好主意,因为当所参考的表发生变化时,数据库必须检查外键约束。 - mu is too short
2个回答

1

8.4版本中的函数参数默认情况下是隐式的CONSTANT,除非它们是OUT参数。我找不到在8.4文档中指定这一点的地方,但我找到了一些有关从Informix转换到PostgreSQL的相关讨论:

看起来你可以通过声明一个同名的局部变量来模拟一个可变函数参数:

create or replace function pref_update_rep(_id varchar,
        _author varchar, _author_ip inet,
        _good boolean, _fair boolean, _nice boolean,
        _about varchar) returns void as $BODY$
        declare
        rep integer;
        _author varchar := _author;
        begin

可能有点笨拙,将来看起来可能会令人困惑,但或许这比其他选择更可取。

0

它运行在PostgreSQL 9.0.2中。也许需要升级。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接