2012-08-07 57 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