Perl中的表光标

时间:2012-02-13 20:17:49

标签: database perl postgresql cursor dbi

我想迭代一个不适合内存的大表。

在Java中,我可以使用游标并根据需要加载内容而不会溢出内存。我如何使用Perl做同样的事情?

我正在使用的数据库是PostgreSQL和DBI。

4 个答案:

答案 0 :(得分:3)

只需在PostgreSQL中使用数据库游标即可。 manual

中的一个示例
BEGIN WORK;

-- Set up a cursor:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;

-- Fetch the first 5 rows in the cursor liahona:
FETCH FORWARD 5 FROM liahona;

 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           | 101 | 1949-12-23 | Drama    | 01:44
 BL102 | The African Queen       | 101 | 1951-08-11 | Romantic | 01:43
 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
 P_301 | Vertigo                 | 103 | 1958-11-14 | Action   | 02:08
 P_302 | Becket                  | 103 | 1964-02-03 | Drama    | 02:28

-- Fetch the previous row:
FETCH PRIOR FROM liahona;

 code  |  title  | did | date_prod  |  kind  |  len
-------+---------+-----+------------+--------+-------
 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08

-- Close the cursor and end the transaction:
CLOSE liahona;
COMMIT WORK;

答案 1 :(得分:3)

我使用PostgreSQL数据库中的PostgreSQL游标。

my $sql = "SOME QUERY HERE";
$dbh->do("DECLARE csr CURSOR WITH HOLD FOR $sql");
my $sth = $dbh->prepare("fetch 100 from csr");
$sth->execute;

while(my $ref = $sth->fetchrow_hashref()) {     
    //... - processing here
    if ($count % 100 == 0){             
        $sth->execute;
    }
}

答案 2 :(得分:1)

出了什么问题:

my $s = $h->prepare(select ...);
$s->execute;
while(my $row = $fetchrow_arrayref) {
  ; # do something
}

答案 3 :(得分:0)

以DBD :: Pg docs为例。

在while()循环中使用DBI fetchrow_ *函数进行较小的内存分配,避免fetchall _ *。

与内存使用相关的其他数据库选项:

  • LongReadLen - “long”类型字段的最大长度(LONG,BLOB,CLOB,MEMO等)
  • RowCacheSize(未在DBD :: Pg中使用) - 驱动程序的提示,指示应用程序希望驱动程序用于将来的“SELECT”语句的本地行缓存的大小。