关于 Pl/pgsql 中游标的一些错误

Posted

技术标签:

【中文标题】关于 Pl/pgsql 中游标的一些错误【英文标题】:Some error about cursor in Pl/pgsql 【发布时间】:2016-05-03 14:27:33 【问题描述】:

我知道从表中插入值的正确方法:insert into city (pop) select pop+2 from city 我只是想知道游标在 Pl/pgsql 中是如何工作的。 我希望在循环中使用游标来插入一些值:

create or replace function test(  ) returns void as 
$$
declare
cur cursor for select pop+2 from city order by pop;
b int;
row record;
begin
for row in cur
LOOP 
fetch cur into b;
insert into city(pop) select b;
end loop;
end;
$$ language plpgsql    

但是,当我输入select test() 并且结果表是:

很奇怪,只插入了两行。所以我想知道是什么导致了这个结果?

在 2016 年 4 月 5 日更新我的问题: 我这样修改函数:

create or replace function test(  ) returns void as 
$$
declare
cur cursor for select * from city order by pop;
b record;
begin
for b in cur
LOOP 
insert into city(pop) select b.pop+2;
RAISE NOTICE ' % IS INSERTED' , b;
end loop;
end;
$$ language plpgsql

然后我得到正确的结果:

但我还是想知道为什么在第一个函数中,只插入了两行。

【问题讨论】:

你为什么首先使用(缓慢且低效的)光标?您可以使用单个语句更有效地完成此操作insert into city (pop) select pop+2 from city; 只是猜测:在你的循环中有两个提取:第一个是隐式的,在for row in cur LOOP,第二个是显式的,在fetch cur into b;。因此,在每次迭代中,您实际上都在进行两次提取。 【参考方案1】:

我终于弄清楚为什么结果是错误的,就像 Abelisto's comment 一样。我在每一步都在loop 中做了两个提取器:

    for row in cur LOOPfetch cur into b

所以第一行where pop=500和第三行pop =1000已经在for loop中取到了,b取不到。

【讨论】:

以上是关于关于 Pl/pgsql 中游标的一些错误的主要内容,如果未能解决你的问题,请参考以下文章

用于行 mod 3 的 PL/pgSQL 游标

在 PL/pgSQL 中实现游标功能作为分页

PL/pgSQL 中 PL/SQL %NOTFOUND 的等价物是啥?

PL/pgSQL 代码的问题

PL/pgSQL 中的光标

PL/pgSQL 中的“格式错误的数组文字”错误