2012-05-11 99 views
2

在Oracle OCI和OCCI中,有一些API工具可用於執行數組插入,以便在客戶機中構建一個值數組,並將此數組與準備好的語句一起發送到服務器以將數千個條目插入在一次拍攝中的表格可以在某些情況下提高性能。 PostgreSQL中有沒有類似的東西?使用Postgres快速陣列插入

我正在使用股票PostgreSQL C API。

一些僞代碼來說明我有什麼記:

stmt = con->prepare("INSERT INTO mytable VALUES ($1, $2, $3)"); 
pg_c_api_array arr(stmt); 
for triplet(a, b, c) in mylongarray: 
    pg_c_api_variant var = arr.add(); 
    var.bind(1, a); 
    var.bind(2, b); 
    var.bind(3, c); 
stmt->bindarray(arr); 
stmt->exec() 
+1

你在使用什麼語言/ PostgreSQL客戶端API?這對於可以輕鬆使用哪些功能會產生影響。 – Edmund

回答

3

PostgreSQL有類似的功能 - 語句複製和拷貝API - 這是非常快的

libpq documentation

char *data = "10\t20\40\n20\t30\t40"; 

pres = PQexec(pconn, "COPY mytable FROM stdin"); 

/* can be call repeatedly */ 
copy_result = PQputCopyData(pconn, data, sizeof(data)); 
if (copy_result != 1) 
{ 
     fprintf(stderr, "Copy to target table failed: %s\n", 
             PQerrorMessage(pconn)); 
     EXIT; 
} 

if (PQputCopyEnd(pconn, NULL) == -1) 
{ 
     fprintf(stderr, "Copy to target table failed: %s\n", 
              PQerrorMessage(pconn)); 
          EXIT; 
} 

pres = PQgetResult(pconn); 
if (PQresultStatus(pres) != PGRES_COMMAND_OK) 
{ 
     fprintf(stderr, "Copy to target table failed:%s\n", 
              PQerrorMessage(pconn)); 
      EXIT; 
} 

PQclear(pres); 
+0

數據始終是製表符分隔值的行嗎?我認爲如果一列是varchar,那麼必須用引號括起來,或者可能調用PQ轉義函數? – Waslap

+0

你可以使用任何字符如分隔符,選項卡是默認分隔符 - 請參閱COPY doc http://www.postgresql.org/docs/9.1/static/sql-copy.html –

1

由於Pavel Stehule指出,存在COPY命令,並且在C中使用libpq時,會傳輸副本數據的相關函數。我沒有使用過這些。我主要在Python中使用PostgreSQL編程,已經使用了psycopg2中的類似功能。這是非常簡單的:

conn = psycopg2.connect(CONN_STR) 
cursor = conn.cursor() 
f = open('data.tsv') 
cusor.copy_from(f, 'incoming') 
f.close() 

事實上,我也經常更換open與執行一些基本的數據清理第一個類似文件的包裝對象。它非常無縫。

+0

其可惜需要將數據放入首先是一個文件。在我的情況下,我收到一個編碼文件,解碼文件中的值,並希望直接從內存中插入它們。把它們放回到一個新的(PostgreSQL拷貝編碼)文件中似乎是不幸的。 – Waslap

+0

不,您可以在流中使用COPY或直接在字符串中使用數據行。 –

1

我喜歡在單個命令創建幾千行的這種方式:

INSERT INTO mytable VALUES (UNNEST($1), UNNEST($2), UNNEST($3)); 

綁定塔1的值的陣列來$1,第2列的到$2等值的陣列!首先,當您習慣於按行思考時,提供列中的值可能看起來有點奇怪。

對於UNNEST,您需要PostgreSQL> = 8.4或您自己的函數將數組轉換爲集合。