2

在 Oracle OCI 和 OCCI 中,有一些 API 工具可以执行数组插入,您可以在客户端中构建一个值数组,并将该数组连同准备好的语句一起发送到服务器,以便一次将数千个条目插入到表中,从而导致在某些情况下巨大的性能改进。PostgreSQL 中有类似的东西吗?

我正在使用股票 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()
4

3 回答 3

3

PostgreSQL has similar functionality - statement COPY and COPY API - it is very fast

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);
于 2012-05-11T09:04:52.260 回答
1

我喜欢这种在单个命令中创建数千行的方式:

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

将第 1 列的值的数组绑定到$1,将第 2 列的值的数组绑定到$2等等!当您习惯于按行思考时,在列中提供值一开始可能看起来有点奇怪。

您需要 PostgreSQL >= 8.4 forUNNEST或您自己的函数来将数组转换为集合。

于 2013-06-10T09:19:12.527 回答
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用一个类似文件的包装器对象替换它,它首先执行一些基本的数据清理。它非常无缝。

于 2012-05-11T09:49:34.050 回答