2012-08-07 61 views
0

我使用libdbi连接到一个大型postgresql数据库(3亿条记录)并执行SELECT *查询,然后逐行显示结果。我得到完整的交换和内存,所以它似乎autocommit已启用,并将整个结果集加载到内存中。有没有任何选项来禁用自动提交或至少保持游标后提交像在ResultSet.HOLD_CURSORS_OVER_COMMIT在Java?我没有找到dbi_conn_set_option的任何选项来做到这一点。这里是我的代码:如何在libdbi中使用游标 - postgresql

dbi_conn conn; 
dbi_result result; 
int64_t id; 

dbi_initialize(NULL); 
conn = dbi_conn_new("pgsql"); 

if (conn == NULL) 
{ 
    printf("connection error.\n"); 
return EXIT_FAILURE; 
} 

dbi_conn_set_option(conn, "host", "127.0.0.1"); 
dbi_conn_set_option(conn, "username", "postgres"); 
dbi_conn_set_option(conn, "password", "123456"); 
dbi_conn_set_option(conn, "dbname", "backup"); 

if (dbi_conn_connect(conn) < 0) 
{ 
    printf("could not connect to database.\n"); 
    return EXIT_FAILURE; 
} 

result = dbi_conn_query(conn, "SELECT * FROM tbl"); 
if (result) 
{ 
    while (dbi_result_next_row(result)) 
    { 
     id = dbi_result_get_longlong(result, "_id"); 
     printf("This is _id: %ld\n", id); 
    } 

    dbi_result_free(result); 
} 

dbi_conn_close(conn); 
dbi_shutdown(); 

回答

1

这与autocommit无关。

内存不足问题的解决方案确实是使用游标一次获取N个结果,而不是一步完成所有结果。

libdbi没有为SQL游标提供抽象,所以需要用SQL查询来完成。

该文档的page on FETCH在其示例中有一个完整的查询序列,显示了如何完成。您需要用C语言中的libdbi调用这些查询,并使用两个循环:一个外循环调用FETCH N from cursor_name,直到没有什么可以提取,并且内循环处理该FETCH的结果,就像处理select *本身的结果的当前代码一样。

+1

至少当使用Java/JDBC时,使用服务器端游标**与自动提交设置**有关,因为“*后端在事务结束时关闭游标,所以在自动提交模式下,后端将关闭任何东西之前的光标都可以从中获取*“ – 2012-08-07 14:15:27