【问题标题】:Cursor in PL/pgSQLPL/pgSQL 中的光标
【发布时间】:2016-06-04 12:32:52
【问题描述】:

我想在函数中使用游标,但我在定义一个变量时出错,请查看并帮助:)

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;

【问题讨论】:

标签: postgresql function cursor plpgsql


【解决方案1】:

您使用的是哪个版本的 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;

【讨论】:

    【解决方案2】:

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

    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 中的游标

    【讨论】:

      【解决方案3】:

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

      首先,创建一个视图:

      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;
      

      【讨论】:

        猜你喜欢
        • 2018-09-01
        • 1970-01-01
        • 2017-05-07
        • 1970-01-01
        • 1970-01-01
        • 2013-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多