关于 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 LOOP
,
fetch cur into b
所以第一行where pop=500
和第三行pop =1000
已经在for loop
中取到了,b
取不到。
【讨论】:
以上是关于关于 Pl/pgsql 中游标的一些错误的主要内容,如果未能解决你的问题,请参考以下文章