- 论坛徽章:
- 0
|
http://www.wohedb.com/db_html_doc/libpq_api/libpq_4_async.htm
http://www.wohedb.com/index.html 中文数据库管理系统
1.4 异步函数
使用函数PQexec执行SQL命令很方便,但也有下面的缺点:
· PQexec 必须等到发出的命令执行结束才会返回,如果命令执行的时间比较长,应用程序将长时间处于等待状态,不能响应用户的其它请求,降低了程序的交互性。
· PQexec如果一次执行多条命令,只有最后一条命令的PGresult才会被返回,前面的命令的PGresult会被丢弃。
Libpq同时提供了异步函数来执行SQL命令,这些函数不用等到命令执行完就可以返回。但这些异步函数使用起来比PQexec这样的同步函数要复杂得多。下面列出了这些函数:
PQsendQuery
发送一条命令给服务器,然后立即返回。返回值是1表示命令成功地传给服务器。返回值是0表示命令没有成功地传给服务器(调用函数PQerrorMessage得到详细的错误信息)。
int PQsendQuery(PGconn *conn, const char *command);
PQsendQuery执行成功以后,调用PQgetResult一次或多次来得到查询返回的结果。直到PQgetResult返回一个空指针,才能在同一个连接上再次调用PQsendQuery。
PQsendQueryParams
发送一个命令给数据库执行,然后立即返回。这个函数可以执行带参数的SQL命令。
Submits a command and separate parameters to the server without waiting for the result(s).
int PQsendQueryParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
函数的参数与PQexecParams一样。一次只能执行一条SQL命令。
PQsendPrepare
发一个请求给数据库,要求创建一个准备好的SQL语句,然后立即返回。
int PQsendPrepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);
它是PQprepare的异步版本,它的参数与PQprepare也是一样的。返回1表示请求成功地传给服务器。返回0表示请求没有成功地传给服务器。函数执行成功以后,调用PQgetResult确定准备好的语句是否被成功地创建。
PQsendQueryPrepared
给服务发送一个执行一条准备好的语句的请求,然后立即返回。
int PQsendQueryPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
它的参数与PQexecPrepared是一样的。
PQsendDescribePrepared
给服务发送一个得到一条准备好的语句的信息的请求,然后立即返回。
int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
这个函数的参数与PQdescribePrepared是一样的。返回1表示请求成功地传给服务器。返回0表示请求没有成功地传给服务器。函数执行成功以后,调用PQgetResult得到命令执行的结果。
PQgetResult
取前面被调用的PQsendQuery、PQendQueryParams、PQsendPrepare或PQendQueryPrepared函数发出的命令的下一个执行结果。如果返回一个空指针表示命令已经执行结束,所有的结果已被取回。
PGresult *PQgetResult(PGconn *conn);
应当多次重复调用这个函数直到它返回一个空指针,表示前面发出的命令已经执行结束。如果没有命令在执行,PQgetResult会立即返回一个空指针。注意调用PQgetResult时,它可能会处在等待状态,因为命令仍然在执行,结果还没有产生。
如果一条命令包含多条SQL查询,使用PQgetResult就能得到每一个SQL查询返回的查询结果。因为调用PQgetResult时,仍然可能进入等待状态, Libpq提供了PQconsumeInput和PQisBusy 这两个函数来解决这个问题:
PQconsumeInput
如果服务器有数据要发送给客户端,直接读这些数据到客户端。
int PQconsumeInput(PGconn *conn);
函数返回1表示执行成功,函数返回0表示执行失败(调用PQrrorMessage得到详细的错误信息)。
PQisBusy
返回1表示发送给服务器的命令正在执行,如果调用PQgetResult,会处于等待的状态。返回0表示服务器已经准备好数据,调用PQgetResult可以立即得到命令执行的结果。
int PQisBusy(PGconn *conn);
PQisBusy不会尝试从服务器读数据,必须先调用PQconsumeInput,再调用PQisBusy。
使用PQsendQuery/PQgetResult进行异步命令处理的客户端也可以调用PQcancel终止一个正在被服务器执行的命令,详细信息参考本章第1.5小节。但即使一个命令被终止执行以后,客户端也必须调用PQgetResult得到命令已经返回的结果,PQcancel只是让一个命令提前结束执行,但这个命令结束以前产生的结果仍然是有效的。
如果客户端发送很长的命令给服务器或者使用COPY IN传送大量数据给服务器,此时客户端可能在传送数据的过程中处于等待的状态。Libpq提供了下面的函数可以让数据库连接在非阻塞的状态下运行。
PQsetnonblocking
设置数据库连接的阻塞模式。
int PQsetnonblocking(PGconn *conn, int arg);
如果参数arg的值是1,连接将处于非阻塞模式。如果参数arg的值是0,连接将处于阻塞模式。函数返回0表示执行成功,函数返回-1表示执行失败。
如果连接处于非阻塞模式,函数PQsendQuery和PQendcopy如果不能立即将数据传递给服务器,将立即返回一个错误,而不是进入等待状态。
函数PQexec不受连接的阻塞模式的影响,无论连接是否处于阻塞模式,它都会等到命令执行完以后才返回。
PQisnonblocking
返回数据库连接的阻塞模式。
int PQisnonblocking(const PGconn *conn);
返回1表示连接处于非阻塞模式,返回0表示连接处于阻塞模式。
PQflush
将客户端所有的还没有发送给服务器的数据发送给服务器。如果成功,返回0。如果遇到错误,返回-1。返回1表示只成功地发送了一部分数据(只有在连接处于非阻塞的模式下才可能返回1)。
int PQflush(PGconn *conn);
在非阻塞的连接上发送了任何命令给数据库以后,都应该调用PQflush。如果它返回1,应该等待一段时间后再调用PQflush,直到它返回0。
[ 本帖最后由 postgres_fan 于 2009-5-17 09:45 编辑 ] |
|