这是一个SQL学习练习。我有一个带有单个整数字段的'tbl'。这张桌子上没有指数。我有这个功能:
CREATE OR REPLACE FUNCTION rcs()
RETURNS VOID AS $$
DECLARE
c CURSOR FOR SELECT * FROM tbl ORDER BY sequence;
s INTEGER;
r RECORD;
BEGIN
s := 0;
OPEN c;
LOOP
FETCH c INTO r;
EXIT WHEN NOT FOUND;
RAISE NOTICE 'got it';
r.sequence = s;
s := s + 1;
RAISE NOTICE '%', r.sequence;
END LOOP;
CLOSE c;
END;
$$ language 'plpgsql'
这会加载并运行干净,RAISE语句表明'sequence'字段根据ORDER BY更新为0,1等。
然而,当我之后选择表时,预先存在的值(碰巧都是'6')没有改变。
这与交易有关吗?我试图摆弄COMMIT等等无济于事。
这是一个新安装的Postgresql 9.4.4,在Linode上运行,没有任何配置文件或类似的东西,来自'psql'命令行。
编辑:也许是因为'r'实际上不是数据库表,它是某种临时副本吗?如果是这样,请澄清一下,希望我在这里想要实现的目标是显而易见的(我知道这可能有点荒谬,但肯定有可能无需借助于将集合读入Java等)。答案 0 :(得分:2)
实际问题:您的函数不包含UPDATE
语句,因此不会将任何内容写入磁盘。 r.sequence = s;
只是为内存中的变量分配一个新值。
要解决此问题,您需要以下内容:
UPDATE tbl
set sequence = s -- change the actual column in the table
WHERE current of c; -- for the current row of your cursor
如果where current of
不起作用,您需要将其切换为"常规" where
条款:
UPDATE tbl
set sequence = s
WHERE tbl.pk_column = r.pk_column; -- the current primary key value
但更有效的解决方案是在一个声明中执行此操作:
update tbl
set sequence = tu.new_sequence
from (
select t.pk_column,
row_number() over (order by t.sequence) as new_sequence
from tbl t
) tu
where tbl.pk_column = tu.pk_column;
您需要将列名pk_column
替换为表的真实主键(或唯一)列。