PL / pgSQL中的游标

时间:2016-06-04 12:32:53

标签: postgresql function cursor plpgsql

我想在函数内部使用游标但是我有一个关于一个变量定义的错误,请看看并帮助请:)

CREATE OR REPLACE FUNCTION curson_func (
start_date timestamp,
end_date timestamp)
RETURNS SETOF integer AS $$

DECLARE
level_cursor CURSOR FOR 
SELECT
    login_event.player_id,
    registration.country_id
FROM
    "fish-tsg".registration
LEFT JOIN
    "fish-tsg".login_event USING (player_id)
WHERE
    ts >= start_date AND ts <= end_date ;

level_cursor_row "fish-tsg".login_event%ROW_TYPE;

BEGIN 
OPEN level_cursor;
LOOP FETCH level_cursor INTO level_cursor_row;
EXIT WHEN level_cursor_row = null;
END LOOP;
CLOSE level_cursor;

RETURN level_cursor_row;

END $$
LANGUAGE 'plpgsql';

我得到的错误:

ERROR:  invalid type name ""fish-tsg".login_event%ROW_TYPE"
LINE 20: level_cursor_row "fish-tsg".login_event%ROW_TYPE;

3 个答案:

答案 0 :(得分:0)

您使用的是哪个版本的PostgreSQL?你的语法是(除了代码中的许多错误)非常古老的风格,现在它变得容易多了。例如:

CREATE OR REPLACE FUNCTION cursor_func (_start_date timestamp, _end_date timestamp) RETURNS TABLE (player_id int, country_id int) AS $BODY$
DECLARE
  _level record;
BEGIN 
  FOR _level IN -- cursor is opened automatically
    SELECT login_event.player_id, registration.country_id
    FROM "fish-tsg".registration
    LEFT JOIN "fish-tsg".login_event USING (player_id)
    WHERE ts BETWEEN _start_date AND _end_date
  LOOP
    RETURN NEXT _level;
  END LOOP;
  -- note that cursor is auto-closed

  RETURN;
END;
$BODY$ LANGUAGE plpgsql;

但是如果没有光标,你应该可以从更简单的方式中受益:

CREATE OR REPLACE FUNCTION cursor_func (_start_date timestamp, _end_date timestamp) RETURNS TABLE (player_id int, country_id int) AS $BODY$
BEGIN 
  RETURN QUERY
    SELECT login_event.player_id, registration.country_id
    FROM "fish-tsg".registration
    LEFT JOIN "fish-tsg".login_event USING (player_id)
    WHERE ts BETWEEN _start_date AND _end_date;

  RETURN;
END;
$BODY$ LANGUAGE plpgsql;

更简单:

CREATE OR REPLACE FUNCTION cursor_func (_start_date timestamp, _end_date timestamp) RETURNS TABLE (player_id int, country_id int) AS $BODY$
  SELECT login_event.player_id, registration.country_id
  FROM "fish-tsg".registration
  LEFT JOIN "fish-tsg".login_event USING (player_id)
  WHERE ts BETWEEN $1 AND $2
$BODY$ LANGUAGE sql;

答案 1 :(得分:0)

我有新的东西,但我收到只有一行。问题在哪里?

CREATE OR REPLACE FUNCTION bi.temp_cursor()  
RETURNS refcursor AS
$BODY$
DECLARE
ref refcursor;
ref2 RECORD;

BEGIN
OPEN ref FOR SELECT player_id, ts FROM "fish-tsg".registration LIMIT 100;
FETCH ref INTO ref2;
    LOOP
        RETURN ref2;
        EXIT WHEN NOT FOUND;
    END LOOP;   
END;
$BODY$
LANGUAGE plpgsql;

SQL查询是示例,问题是pl / pgsql中的游标

答案 2 :(得分:0)

也许更好的方法是使用视图而不是函数。

首先,创建一个视图:

CREATE VIEW temp_view
as
SELECT
    login_event.player_id,
    registration.country_id,
    ts
FROM "fish-tsg".registration
LEFT JOIN "fish-tsg".login_event USING (player_id)

然后,使用通常放置表名称的视图名称执行普通选择:

select player_id, country_id
from temp_view
where ts between $start_date AND $end_date;