对于我的Hi / Lo实现,我需要一个获取独占表锁,更新值并选择一行的函数。我想出了以下代码:
CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))
RETURNS setof record AS
$$
LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
OPEN ref FOR SELECT hi as "Hi", lo as "Lo", "table" as "Table" FROM hilo WHERE "table" = $1;
UPDATE hilo SET hi = hi + 1 WHERE "table" = $1
RETURN ref;
$$ LANGUAGE plpgsql;
但是,在调用该函数时,它不返回一行,而是返回一个内容类似于"未命名的门户3"的列。我想我应该迭代返回的ref(但是如何)?
我可以使用的另一种方法是使用UPDATE RETURNING语句,但我不确定在这种情况下是否会出现竞争条件。任何帮助,将不胜感激。感谢
答案 0 :(得分:2)
这对我来说似乎更简单:
CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))
RETURNS setof record AS
$$
BEGIN
LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
RETURN QUERY UPDATE hilo SET hi = hi + 1 WHERE "table" = $1
RETURNING hi as "Hi", lo as "Lo", "table" as "Table";
END;
$$ LANGUAGE plpgsql;
我通常也会定义RETURNS TABLE (col1 varchar, col2 varchar...)
而不是RETURNS setof record
。
答案 1 :(得分:1)
您正在使用cursor
变量(您没有声明,并且缺少其他一些PL / pgSQL必需元素)并且您返回该变量。游标引用确实被称为"门户网站"这样就解释了你的输出。更好的方法是:
CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))
RETURNS TABLE ("Hi" int, "Lo" int, "Table" varchar(35)) AS $$
BEGIN
LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
RETURN QUERY SELECT hi, lo, $1 FROM hilo WHERE "table" = $1;
UPDATE hilo SET hi = hi + 1 WHERE "table" = $1;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT;
但你真的需要一张独家锁吗?获取一致的表快照的入侵方法要少得多。