暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL特性矩阵解析系列10之Holdable cursors

921

概述

    使用DECLARE定义一个游标, 游标可以被用来在大型查询暂停时检索少量的行。游标被创建后,可以用FETCH从中取得行。

     游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。

游标使用

SQL命令级

    postgres=# begin; --开启事务
    BEGIN
    postgres=# declare mycur cursor for select * from user_info;--打开游标
    DECLARE CURSOR
    postgres=# fetch first from mycur;--取第一行数据
    userid | name | birthday | crt_time
    --------+--------+------------+----------------------------
    1 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.239366
    (1 row)
    postgres=# fetch next from mycur;--取下一行数据
    userid | name | birthday | crt_time
    --------+--------+------------+---------------------------
    2 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.23952
    (1 row)

    postgres=# move last in mycur; --游标移动到行尾
    MOVE 1
    postgres=# close mycur;关闭游标
    CLOSE CURSOR
    postgres=# commit;提交
    COMMIT
    复制

    PL/pgSQL函数内使用

      postgres=# create function my_cur(refcursor) returns refcursor as $$
      postgres$# begin
      postgres$# open $1 for select * from user_info;
      postgres$# return $1;
      postgres$# end;
      postgres$# $$language plpgsql;
      CREATE FUNCTION
      postgres=# begin;
      BEGIN
      postgres=# select my_cur('test');
      my_cur
      --------
      test
      (1 row)
      postgres=# fetch first from test;
      userid | name | birthday | crt_time
      --------+--------+------------+----------------------------
      1 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.239366
      (1 row)
      复制

      源码导读

        src/backend/tcop/pquery.c
        /*
        * 对于Portals(客户端请求),有几种执行策略,具体取决于要执行什么查询。
        * (注意:无论什么情况下,一个Portal只执行一个source-SQL查询,因此从用户的角度来看只产生一个结果。
        * 但是,规则重写器可以将单个源查询扩展为零或多个实际查询。
         * 
        * PORTAL_ONE_SELECT: 包含一个SELECT查询。
        * 按需要的结果重复(递增)地运行执行器。
        * 该策略还支持可持有游标(执行器结果可以在事务完成后转储到tuplestore中进行访问)。
         *
        * PORTAL_ONE_RETURNING: 包含一个带有RETURNING子句的INSERT/UPDATE/DELETE查询
        (可能还包括由规则重写添加的辅助查询)。
        * 在第一次执行时,运行Portal来完成并将主查询的结果转储到Portal的tuplestore中;
        * 然后根据需要将结果返回给客户端。
        * (我们不能支持半途中断的查询,因为AFTER触发器代码无法处理,
         *                       也因为不想冒执行所有辅助查询失败的风险)。
        *
        * PORTAL_ONE_MOD_WITH: 只包含一个SELECT查询,但它具有数据修改的CTEs。
        * 这与PORTAL_ONE_RETURNING的情况相同,因为可能需要触发触发器。将来它的行为可能更像PORTAL_ONE_SELECT。
         * 
        * PORTAL_UTIL_SELECT: 包含一个实用程序语句,该语句返回一个类似SELECT的结果(例如,EXPLAIN或SHOW)。
        * 在第一次执行时,运行语句并将其结果转储到portal tuplestore;然后根据需要将结果返回给客户端。
         * 
        * PORTAL_MULTI_QUERY: 除上述情况外的其他情况。
        * 在这里,不支持部分执行:Portal的查询语句将在第一次调用时运行到完成。
        */
        typedef enum PortalStrategy
        {
        PORTAL_ONE_SELECT,
        PORTAL_ONE_RETURNING,
        PORTAL_ONE_MOD_WITH,
        PORTAL_UTIL_SELECT,
        PORTAL_MULTI_QUERY
        } PortalStrategy;

        /* Features/options */
        PortalStrategy strategy; /* 场景;see above */
        int cursorOptions; /* DECLARE CURSOR选项位;DECLARE CURSOR option bits */
        bool run_once; /* 是否只执行一次;portal will only be run once */

        * 在这里,为持有的游标或PORTAL_ONE_RETURNINGPORTAL_UTIL_SELECT存储元组。
        * (在事务结束后持有的游标不再具有任何活动执行器状态。)

        Tuplestorestate *holdStore; /* 存储持有的游标信息;store for holdable cursors */
        MemoryContext holdContext; /* 持有holdStore的内存上下文;memory containing holdStore */
        //用于表示的数据,主要由pg_cursors系统视图使用
        TimestampTz creation_time; /* portal定义的时间;time at which this portal was defined */
        bool visible; /* 是否在pg_cursors中可见? include this portal in pg_cursors? */

           * 游标可滚动,执行器需要支持REWIND和向后的扫描
                if (portal->cursorOptions & CURSOR_OPT_SCROLL)
                     myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
                   else
                     myeflags = eflags;
        复制

        参考

        https://www.postgresql.org/docs/current/sql-declare.html

        http://postgres.cn/docs/12/sql-declare.html

        文章转载自CP的PostgreSQL厨房,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论