2015-09-19 142 views
5

我正在用pgsql脚本语言创建一个函数,而且我想在这一点上执行的操作是迭代查询的结果,并为每一行执行特定的操作。我目前的尝试如下,其中temprow宣布为temprow user_data.users%rowtype。有问题的代码如下:PostgreSQL - 遍历查询结果

FOR temprow IN 
     SELECT * FROM user_data.users ORDER BY user_seasonpts DESC LIMIT 10 
    LOOP 
     SELECT user_id,user_seasonpts INTO player_idd,season_ptss FROM temprow; 
     INSERT INTO user_data.leaderboards (season_num,player_id,season_pts) VALUES (old_seasonnum,player_idd,season_ptss); 
    END LOOP; 

但是我从这个出现以下错误:ERROR: relation "temprow" does not exist。如果我很清楚自己想做什么,你能否指出正确的做法?

+2

做这将是正确的做法:“dont't迭代”。你似乎做的是完全可行的使用普通的SQL:'插入到排行榜(a,b,c)从用户中选择x,y,z;' – wildplasser

+0

正如我在答案中注意到的那样,old_seasonnum此时未被选中来自'user_data.users',但在之前的一点。 –

+0

允许在需要表达式的地方使用常量(或在plpgsql或准备语句中的变量):'insert into foo(a,b,c)从bar中选择42,y,z;'注意:在你的代码'old_seasonnum'甚至没有定义。 – wildplasser

回答

16

temprow是一个记录变量,它依次绑定到第一个SELECT的每个记录。

所以,你应该写:

FOR temprow IN 
     SELECT * FROM user_data.users ORDER BY user_seasonpts DESC LIMIT 10 
    LOOP 
     INSERT INTO user_data.leaderboards (season_num,player_id,season_pts) VALUES (old_seasonnum,temprow.userd_id,temprow.season_ptss); 
    END LOOP; 

这个循环可以进一步简化为一个单一的查询:

INSERT INTO user_data.leaderboards (season_num,player_id,season_pts) 
SELECT old_seasonnum,player_idd,season_ptss FROM user_data.users ORDER BY user_seasonpts DESC LIMIT 10 
+0

'FOR' /'temprow'是游标吗?它会做任何锁定吗? – Ruslan

+1

是的,它是一个游标,但没有锁定在用户表 – Renzo

+0

简化的单个查询的问题是,'old_seasonnum'不是从'user_data.users'表中选择的,而是从之前的select中选择的在这一点上使用。 –