【问题标题】:Some error about cursor in Pl/pgsql关于 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;。因此,在每次迭代中,您实际上都在进行两次提取。

标签: postgresql cursor plpgsql


【解决方案1】:

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

  1. for row in cur LOOP
  2. fetch cur into b

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多