pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
Postgres 中的 COPY 命令可以选择从 libpq 所用的网络连接读取或向其写入。因此,需要能直接访问此网络连接的函数,应用才能利用这一能力。
只有在从 PQexec 或 PQgetResult 得到 PGRES_COPY_OUT 或 PGRES_COPY_IN 结果对象之后,才应执行这些函数。
PQgetline 把一行由后端服务器传来的以换行符结尾的字符读入大小为 length 的缓冲区字符串。
int PQgetline(PGconn *conn,
char *string,
int length)
与 fgets(3) 一样,此例程最多把 length-1 个字符复制到 string 中;但与 gets(3) 相似,它会把结尾的换行符转换为空字符。 PQgetline 在 EOF 处返回 EOF,整行已读完返回 0,缓冲区已满但 结尾换行符尚未读到。 注意,应用必须检查新的一行是否由两个字符 "\." 组成,这表示后端服务器已发送完 copy 命令的结果。如果应用可能收到超过 length-1 个字符的行,就需要小心确保正确识别 "\." 行(例如,不要把长数据行的结尾误当作终结行)。 ../src/bin/psql/psql.c 中的代码包含正确处理 copy 协议的例程。
PQgetlineAsync 把一行由后端服务器传来的以换行符结尾的字符读入缓冲区而不阻塞。
int PQgetlineAsync(PGconn *conn,
char *buffer,
int bufsize)
此例程类似于 PQgetline,但可供必须异步(即不阻塞地)读取 COPY 数据的应用使用。发出 COPY 命令并得到 PGRES_COPY_OUT 响应后,应用应交替调用 PQconsumeInput 和 PQgetlineAsync,直到检测到数据结束信号。与 PQgetline 不同,此例程自己负责检测数据结束。 每次调用时,如果 libpq 的输入缓冲区中已有完整的一行以换行符结尾的数据行,或者到来的数据行太长放不进调用者提供的缓冲区,PQgetlineAsync 就会返回数据。否则,在该行剩余部分到达之前不返回数据。 如果已识别到 copy 数据结束标记,此例程返回 -1;没有可用数据返回 0;返回正数时该数给出所返回数据的字节数。返回 -1 时,调用者接下来必须调用 PQendcopy,然后回到正常处理。 返回的数据不会跨过换行符。可能时一次返回整行;但如果调用者提供的缓冲区太小装不下后端发来的一行,就会返回部分数据行。这可以通过检查最后返回的字节是否为 '\n' 来检测。返回的字符串不以空字符结尾。(如果想加上结尾空字符,务必让传入的 bufsize 比实际可用空间小一。)
PQputline 向后台服务器发送一个以空字符结尾的字符串。成功返回 0,无法发送字符串返回 EOF。
int PQputline(PGconn *conn,
char *string);
注意,应用必须在最后一行显式发送两个字符 "\.",以告知后端它已发送完数据。
PQputnbytes 向后台服务器发送一个不以空字符结尾的字符串。成功返回 0,无法发送字符串返回 EOF。
int PQputnbytes(PGconn *conn,
const char *buffer,
int nbytes);
它与 PQputline 完全一样,只是由于要发送的字节数是直接指定的,数据缓冲区不需要以空字符结尾。
PQendcopy 与后端同步。此函数等待后端完成 copy。它应当在用 PQputline 向后端发送完最后一个字符串之后,或用 PGgetline 从后端收到最后一个字符串之后发出。必须发出此函数,否则后端可能与前端"out of sync"(失去同步)。从此函数返回后,后端就准备好接收下一条查询了。成功完成时返回值为 0,否则非零。
int PQendcopy(PGconn *conn);
举一个例子:
PQexec(conn, "create table foo (a int4, b char(16), d float8)"); PQexec(conn, "copy foo from stdin"); PQputline(conn, "3\thello world\t4.5\n"); PQputline(conn,"4\tgoodbye world\t7.11\n"); ... PQputline(conn,"\\.\n"); PQendcopy(conn);
使用 PQgetResult 时,应用对 PGRES_COPY_OUT 结果的响应应是反复执行 PQgetline,看到终结行后再执行 PQendcopy。然后应回到 PQgetResult 循环,直到 PQgetResult 返回 NULL。类似地,PGRES_COPY_IN 结果由一系列 PQputline 调用加 PQendcopy 处理,然后回到 PQgetResult 循环。这样的安排可确保嵌入在一系列 SQL 命令中的 copy in 或 copy out 命令被正确执行。 较老的应用可能通过 PQexec 提交 copy in 或 copy out,并认为 PQendcopy 之后事务就完成了。只有当 copy in/out 是查询字符串中唯一的 SQL 命令时,这样做才是正确的。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。