PostgreSQL数据库学习手册之libpq_第1页
PostgreSQL数据库学习手册之libpq_第2页
PostgreSQL数据库学习手册之libpq_第3页
PostgreSQL数据库学习手册之libpq_第4页
PostgreSQL数据库学习手册之libpq_第5页
已阅读5页,还剩71页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PostgreSQL数据库学习手册之libpq-C库—介绍(转)[@morc@]

ChapterLlibpq-C库

TableofContents

l.k介绍

1.2.数据库联接函数

1.3。命令执行函数

1.3。1.主过程

U3。2。为包含在SQL杳询中逃逸字串

1.3。3.逃逸包含在SQL查ifU中的二进制字串

1.3。4。检索SELECT的结果信息

1.3.5«检索SELECT结果数值

1。3。6.检索非一SELECT结果信息

1.4.异步查询处理

1.5.捷径接口

E6。异步通知

1.7.与COPY命令相关的函数

1。8。libpq跟踪国数

I。901ibpq控制函数

1。10。环境变量

1.H.文件

1.12.线程特性

1.13o制作Libpq程序

1。14。例子程序

1.1。介绍

1ibpq是PosigreSQL的C应用程序员的接口.1ibpq是一套允卢客户程序向PostgreSQL后

端服务进程发送查询并且获得查询返回的库过程.libpq同时也是其他几个PostgreSQL应用接口下

面的引擎,包括libpq++(C++),1ibpgtc1(Tel),Perl,和ecpg.所以如果你使用这些软件包,

1ibpq某些方面的特性会对你非常里要.

本节末尾有三个小程序显示如何利用libpq书写程序.在下面目录里面有几个完整的1ibpq应用的

例子:

src/test/examp1es

src/bin/psql

使用libpq的前端程序必须包括头文件libpq-fe.h并且必须与Iibpq库链接.

PosigreSQL数据库学习手册之1ibpq-C库——数据库联接函数(转)[@more@]

1.2.数据库联接函数

下面的过程处理与PostgreSQL后端服分踞联接的事情.•个应用程宇•次可以与多个后端建立联接.

(这么做的原因之一是访问多于一个数据库.)每个连接都是用一个从PQconnectdb(〃&PQsetdbLo

gin()获得的PGconn对象表示.注意,这些函数总是返回一个非空的对象指针,除非存储器少得

连个PGconn对象都分配不出来.在把查询发送给联接对象之前,可以调用PQstalu5函数来检查一下联

接是否成功.

PQconnectdb与后端数据库服务器建立一个新的联接.

PGconn*PQconnectdb(constchar*conninfo)

这个过程用从一个字符串conninfo来的参数与数据库打开一个新的联接.与下面的PQsetdbLogin()

不同的是.我们可以不必更换函数签名(名字)就可以扩展参数集,所以我们建议应用程序中使用这个函

数或者是它的非阻塞的相似函数PQconnectStart和PQconneciPoll.传入的参数可以为空,表明

使用所有缺省的参数,或者可以包含一个或更多个用空白间隔的参数设置.

每个参数以关键字=数值的形式设置.(要写•个空值或者•个包含空白的值,你可以用•对单引号包

围它们,伊妆口,keyword='avalue,.数值内部的单引号和反斜扛必须用一个反斜扛逃逸,也

就是说,'或.)等号周围的空白是可选的.目前可识刖的参数键字是:

host

要联接的主机(host).如果主机名以斜扛开头,则它声明使用Unix域套接字通讯而不是TCP/IP

通讯;该值就是套接字文件所存储的目录.缺省时是与位于/tmp里面的Unix一域套接字联接.

hostaddr

与之联接的主机的IP地址。这个可以是标准的数字一点的形式,象在BSD函数inet_aton等里面用的

那样。如果声明了一个非零长的字符串,那么使用TCP/IP通讯机制.

使用hostaddr取代host可以让应用避免一次主机名查找,这一点对于那些书■时间约束的应用来

说可能是非常重要的。不过,Kerberos认证系统要求主机(h。st)名。因此,应用下面的规则。如果声

明了不带hostaddr的host那么就强制进行主机名查找。如果声明中没有host,hostaddr的

值给出远端的地址:如果使用了Kerberos,将导致一次反向名字查询.如果同时声明了h。st和h

usIadd1,除非使用了KeIbe1us,否则带使用husluddr的值作为远端地址;h。sl的值将被忽略,

如果使用了Kerberos,host的值用于Kerberos认证。要注意如果传递给libpq的主机名(ho

st)不是地址hostaddr处的机涔名,那么认证很有可能失败。

如果主机名(host)和主机地址都没有,那么libpq将使用一个本地的Unix域套接字进行通讯。

port

主机服务器的端口号,或者在Unix域套接字联接时的套接字扩展文件名.

dbname

数据库名.

user

要联接的用户名。

Password

如果后端要求口令认证,所用的口令.

conncct_timcout

给连接过程设置的时间范围,以秒计。零或者不设置表示无穷。

options

发给后端的跟踪/调试选项.

tty

文件或控制台(tty),用于从后端的可选调试输出.

requiressl

设为要求与后端进行SSL联接.如果股务器不支持SSL,那么Libpq将马上拒绝联接.设置

为’0'(映省)与服务器进行协商.

如果有任何没有声明的参数,那么将检查对应的环境变量(参阅Section1.10小节).如果环境变珏也

没有设置,那么使用编译时的硬代码.返回的值是一个指向代表与后端联接的抽象struct指针。

*

PQsetdbUgin与后端数据库服务器建立一个新的联接.

PGconn*PQsetdbLogin(constchar*pghost,

constchar*pgport,

constchar*pgoptions,

constchar*pgtty»

constchar*dbName,

constchar*1ogin,

constchar*pwd)

这个函数是PQconnecidb前身,它有固定个数的参数,但是有相同的功能.

*

PQsetdb与后端数据库服务器建立一个新的联接.

PGconn*PQsetdb(char*pghast,

char*pgport,

char*pgoptions,

char*pgtty,

char*dbNamc)

这是一个调用PQsetdbLogin()的宏,只是login和pwd参数用空(null)代替.提供这个

函数主要是为了与老版本的程序兼容.

*

PQconncctStart,PQconncctP3l1与数据库服务卷建立•诙非阻塞的联接。

PGconn*PQconnectStart(constchar+conninfo)

PostgreSQI.PoIlingStatusTypePQconnectPol1(PGconn*conn)

这两个过程用于打开一个与数据库服务器之间的非阻塞的联接:你的应用的执行线索在执行它的时候不会

因远端的I/O而阻塞。

数据库联接是用从conninf。字符串里取得的参数传递给PQc。nnectStart进行的。这个字符申

的格式与上面PQconncctdb里描述的样。

PQconnectStart和PQconnectPo11都不会阻塞(进程),不过有一些条件:

必须正确提供hostaddr441host参数以确保不会发生止向或者反向的名字查找。参阅上面HQconnect

db里的这些参数的文档获取细节。

如果你调用了PQtrace,确保你跟踪进入的流对象不会阻塞。

你必须在调用PQconnectPoll之前确保socket处于正确的状态,象下面描述的那样。

要开始(联接)»调用conn=PQconnectStart(*connection_info_string*).如果conn是N

ULL,表明libpq无法分配一个新的PGconn结构。否则,返PJ一个It效的PGconn指针(尽管还不一

定代表一个与数据库有效联接)。PQconnectStart一返回,调用status-PQstatus(conn)如果stat

us等于CONNECTION_BAD,PQconnectStart失败。

如果PQconneclSlari成功了,下一个阶段是轮询1ibpq,这样它就可以继续进行后继的联接动作。象

这样循环:认为一个联接缺省时是‘不活跃”的.如果PQconnectPoll的最后一个返回是PGRE

S_POLLING_ACTIVE,则认为它是“活跃的"。如果PQconnectPolI(conn)的最后一个返回是P

GRESPOLLINGREADING,执行一个对PQsockct(conn)的读sclect().如果最后一个返回是PG

RES.POLLINGWRITING,执行一个对PQs。cket(conn)的写select().如果还要调用PQconn

ectPoll,也就是调用完PQconnectstart之后,把它当作最后返回PGRES一POLL1NG_WRITING那样对

待。如果select。显示sockel已经准备好,那么认为它是“活跃的”。如果认为一个联接是”

活跃的",再次调用PQconnectPolI(conn)o如果这次调用返回PGRES_POLLING_FAILED,联接

过程失败,如果这次调用返回PGRES.POLLING_0K,联接成功。

要注意上面用sol。ct0来确保一个socket准备好只是一个(近似)的例子;还可以用其他方法,

比如一个pol1。调用,来代替select。

在联接的任意时刻,我们都可以通过调用PQstatus来检查联接的状态。如果这是CONNECTION_BAD,

那么联接过程失败:如果是CONNECTION0K,那么联接已经做好。这两种状态同样也可以从上面的K

connectPoll的返回值里检测到。其他状态可能(也只能)在一次异步联接过程中看到。这些标识联接

过程的当前状态,因而可能对给用户提供反馈有帮助。这些状态可能包括:

CONNECTIONSTARTED

等待进行联接。

CONNECTIONMADE

联接成功:等待发送.

CONNECTION_AWAIT1NG_RESPONSE

等待来fl服务器的响应。

CONNECTION_AUTH_OK

己收到认证;等待联接启动继续进行。

CONNECTION.SETENV

协商环境(联接启动的一部分)。

注意,尽管这些常量将保持下去(为了维持兼容性),应用决不应该依赖于这些常量的某种特定顺序,或

者是根本不应依赖r这些常量,或者是不应该依赖:这些状念总是某个义档声明的值。一个应用可能象

象下面这样:

switch(PQstatus(conn))

(

caseC0NNECTI0N_STARTED:

feedback=*Connecting....*:

break;

caseCONNECTIONMADE:

feedback="Connected1oserver。..”;

break;

defau1t:

feedback="Connecting..«

)

要注意如果PQconnectStart返回一个非空的指针,你必须在使用完它(指针)之后调用PQfinish,

以处理那些结构和所有相关的存储块。甚至调用PQconnectStart或者PQconnectPo11失败时也

要这样处理。

如果编译libpq时定义了USE_SSL那么目前的PQconnectPoll将阻塞住。这个限制可能在将

来的版本移除.

这些函数把socket置于一个非阻塞的状态,就好象调用了PQsetnonb1ocking一样。

*

PQconndefaults返向缺省的联接选项。

PQconninfoOption*PQconndefau1ts(void)

structPQconninfoOption

(

char*keyword:/*Thekey*ordoftheoption*/

char*envvar:/*Fai1backenvironmentvariablename*/

char*compiled:/*Fa1IbackcompiledindefauItva1ue*/

char*vaI;/*Option'scurrentvalue,orNULL♦/

char*label;/*Labelforfieldinconnectdialog*/

char+dispchor;/*Charoctertodisplayforthisfield

inaconncctdialog。Valuesare:

”"Displayenteredvalueasis

"*"Passwordfield-hidevalue

"D"Debugoption-don'tshowbydefault*/

intdispsize:/*Fie1dsizeincharactersfordialog*/

)

返回联接选项结构的地址.可以用于获取所有可能的PQconnectdb选项和它们的当前缺省值.返回值

指向一个PQconninfoOplionstruct的数组,该数组以一个有NULL关键字指针的条目结

束.注意缺省值(val域)将依赖于环境变量和其他上下文.调用者必须把联接选项当作只读对待.

在处理完选项数组后,把数组交给PQconninfoFree()糅放.如果没有这么做,每次调用PQc。nndefa

ults()都会有一小部分内存泄漏.

在PostgreSQL7。0以前的版本,PQconndefau1ts()返回一个指向群态数组的指针,而不是一

个动态分配的数组.这样做是线程不安全的,因此这个特点被修改了.

*

PQfinish关闭与后端的联接.同时糅放被PGconn对象使用的存储器.

voidPQfinish(HGconn*conn)

注意,即使与后端的联接尝试失败(可由PQstatus判断),应用也要调用PQfinish释放被PGeon

n对象使用的存储器.不应该在调用PQfinish后再使用PGconn指针.

PQresel重置与后端的通讯端口.

voidPQreset(PGconn*conn)

此函数将关闭与后端的联接并且试图与同一个服务器重建新的联接,使用所有前面使用过的参数.这在失

去工作联接后进行故障恢复时很布•用.

PQresetSiartPQreseiPoll以非阻塞模式重置与后端的通讯端口。

intPQresetStart(PGconn*conn);

PostgreSQLPol1ingStatusTypePQresetPol1(PGconn*conn);

此函数将关闭与后端的联接并且试图与同一个服务器重建新的联接,使用所有•前面使用过的参数.这在失

去工作联接后进行故障恢且时很有用.它们和上面的PQreset的区别足它们工作在非阻塞模式。这些

函数的使用有与上面PQconneclStarl和PQconnectPoll一样的限制.

调用PQresetSlari。如果它返回0,那么重置失败。如果返回1,用与使用PQc。nneclPoll建立

联接的同样的方法使用PQresetPo11重置联接。

1ibpq应用程序员应该仔细维护PGc。nn结构.使用下面的访问由数来荻取PGconn的内容.避免直接引

用PGconn结构里的字段,因为这些字段在今后可能被改变.(从PostgreSQL版本6.4开始,struct

PGconn的定义甚至没有放在libpq-fe.h里.如果你有一些直接访问PGconn数据域的旧代码,你

可以通过包含libpq-inteh来访问它们,但我们鼓励你赶快修改那些代码.)

PQdb返回联接的数据库名.

char*PQdb(constPGconn*conn)

PQdb和下面几个函数返回联接时建立起来的几个值.这些值在PGconn对象的生存期内是固定的.

*

PQuser返回联接的用户名.

char*PQuser(constP二conn*conn)

*

PQpass返回联接的口令.

char*PQpass(constPGconn*conn)

*

PQhost返回联接的服务器主机名.

char*PQhost(constPGconn*conn)

*

PQport返叵1联接的端口号.

char*PQport(constPGconn*conn)

女

PQtty返回联接的调试控制台(tty).

char*PQtiy(constFGeonn*conn)

*

PQoptions返回联接中使用的后端选项.

char*PQoptions(constPSconn*conn)

*

PQstatus返回联接的状态.

ConnStatusTypePQstatus(constPGconn*conn)

这个状态可以是一些值之一.不过,如果不是一次异步联接过程的话,我们只能看到其中的两个-CON

NLCT10N_OK或CONNECTION_BAD»一个与数据库的成功的联接返回状态CONNECTIONOK。一次

失败的企图用状态CONNECTION^BAD标识.通常,一个0K状态保持到PQfinish,但是一个通讯失

败可能会导致状态过早地改变为C3NNECTION_BAD。这时应用可以试着调用PQreset来恢复.

参阅PQconnectStart■和PQ,onnectPoll条目看看可能出现的其他的状态码。

*

PQcrrorMessage返回联接中操作产生的最近的错误信息.

char*PQerrorMcssage(c3nsiPGconn*conn);

几乎所有1ibpq函数在失败时都会设置PQerrorMessage,注意libpq的传统是,一个非空的

PQerrorMessage将在结尾包含一■个新行.

*

PQbackendPID返回控制此联接的后端服务器的进程号ID.

intPQbackendPID(constPGconn*conn);

这个后端PID在调试和对比NOTIFY信息(包含发出通知的后端的PID)时很有用.注意该PID

属于运行数据库服务器的主机的进程,而不是本地主机!

*

PQgetssl返回联接使用的SSL结构,或者如果SSL没有使用的话返回NULL.

SSL*PQgetss1(constPGconn*conn);

这个结构可以用于核实加密级别,检查服务器认证等信息.参考SSL文档获取关于这个结构的更多信

息.

为了获取这个函数的原形,你必须定义USESSL.这样做会自动包含来自OpenSSL的ssl.h.

PostgreSQL数据库学习手册之1ibpq-C库命令执行函数(转)[加。re@]

1.3。命令执行函数

一旦与数据库服务器的联接成功建立,便可用这里描述的函数执行SQL杳询和命令。

103.1.主过程

PQexec给股务器提交一条命令并且等待结果.

PGresuit*PQexec(PGconn*conn,

constchar*query);

返回一个PGresu"指针或者也可能是一个NULL指针.通常返回一个非空(non—NUUJ的指针,除

非没有内存或发生了象不能把命令发送到后端这样的严重错误.如果返回的是NULL,它应该被当作

PGRESJ'ATAL_ERROR结果处理.用PQerrorMessage获取有关错误的更多信息.

PGresull结构封装了后端返回的结果.1ibpq应用程序员应该仔细睢护PGresull抽象.用下面的访

问函数来获取PGresu晨的内容避免直接引用PGresu1t结构的数据域,因为这个结构可能会在未

来被改变.(从PostgreSQL版本6。4开始,structPGre$u1t的定义甚至都没有放在

libpq—fe。h里.如果你有一些直接访问PGresuit数据域的老代码,你可以通过包含1ibpq-int.h

继续使用它们,但是我们鼓励你立刻修改代码.)

*

PQresuItStatus返回命令的结果状态.

ExecStatusTypePQresultStatus(constPGresu1t*res)

PQresultStatus可以返回F面数值之一:

o

PGRES_EMPTY_QUERY一一发送给后端的字串是空的

o

PGRES_COMMAND_OK——成功完成一个没有返回数据的命令

n

PGRES_TUPLES_OK——成功执行查询

o

PGRES„COPY_OIT—(从服务器)CopyOut(拷贝出)数据传输开始

o

PGRESCOPYJN一一CopyIn(拷贝入)(到服务器)数据传输开始

PGRES_BAD_RESPONSE一一服务器的响应无法理解

PGRES_NONFATAL_ERROR

o

PGRES_FATAL_ERROR

如果结果状态是PGRESTUPLESOK,那么可以用下面的过程从查询的返回中抽取元组信息.注意一个

碰巧检索了零条元组的SELECT仍然显示PGRESTUPLESOK。PGRESCOVMAND_OK用于不返

回元组的命令(NSERT,UPDATE,等)。返回PGRES_EMPTY_QUERY的响应通常意味着客户端软件

里面的臭虫。

PQresStatus把PQrcsultStatus返网的枚举类型转换成•个描述状态码的字符串常成。

char*PQresStatus(ExecStatusTypestatus);

PQresuItErrorMessage返回与查询关联的错误信息,或在没有错误时返回一个空字符串.

char*PQresultErrorMessage(constPGresu1t*res);

紧跟在一个PQexec或PQgetResult调用后面,PQerrorMessage(对联接)将返回与PQresu

ItErrorMessage(对结果)一样的字符串.不过,一个PGresult将保芍其错误信息直到被删除,而连结

的错误信息将在后续的操作完成时被改变.当你想知道与某个PGresult相关联的状态时用PQresult

ErrorMessage;当你想知道与联接的最近一个操作相关联的状态时用PQerrorMessage:

PQelpar释放于PCr。suit相关联的存储空间任何不再需要的杳询结果在不需要的时候都应该用

PQc1ear释放掉.

voidPQC1ear(PQresu1t*res):

你可以保留PGresult对象任意长的时间:当你提交新的查询时它并不消失,甚至你断开联接后也是

这样.要删除它,你必须调用PQclear.不这么做将导致前端的存储器泄漏.

*

PQmakeEmptyPGresult构造一个给出状态的为空的PGresuIt对象.

PGresult*PQmakeEmptyPGresult(PGconn*conn,ExecStatusTypestatus):

这是libpq的内部过程,用于分配和初始化一个空PGresu1t对象.它被输出是因为一些应用需要自

行生成结果对象(尤其是特定的带有错误状态的对象).如果conn非空(NILL)并且状态指示一个错误,

联接当前的错误信息被拷贝到PGresult.注意最终对该对象要调用PQc】ear,正如1ibpq本身返回的P

Gresu1t一样.

1.3。2.为包含在SQL查询中逃逸字串

PQescapoString为在SQL查询中使用逃逸一个字串.

size_tPQescapeString(char*to,constchar*from,size_tlength):

如果你需要在查询字串中包含一个从不可靠的源头接收的字串(比如,它们是随机用户输入的),那么,出

于安全原因,你不能把它们自按包含在SQL食询里.你应该把特殊字符引起来,否则它们就会被SQL分

析器代换.

PQcscapcString执行这个操伶.fr。m指向将要逃逸的字串的第•个字符,】cngth参数计算在这

个字串里的字符数量(字串结尾的字节零不是必须的,也不计入长度).to应该指向一个缓冲区,这个缓冲

区至少能保存length数值的两倍还多一个的字符,否则该函数行为洛不可预测.调用Ncscape

String就会把逃逸的from字串转换到I。缓冲区,把特殊字符替换掉以免发生意外,并且追加终止的

字节零.那些必须包围在P。sigreSQL字串文本周围的单引号不算结果字串的一部分.

PQescapeString返回写到to甲.面的字符数凡不包括结尾的字节零.如果to和from字串相

互垂登,那么其行为不可预测.

1.3。3.逃逸包含在SQL式谕中的二进制字串

PQescapeBytea逃逸那些在S2L查询中使用二进制字串(bylea类型).

unsignedchar*PQescapeBytea(constunsignedchar*from,

size_tfrom_1ength,

size_t*tolength);

在SQL语句中用做BYTEA字串文本的一部分的时候,有些ASCII字符必需被逃逸(但是对于所有

字符而言是可以逃逸).通常,要逃逸一个字符,它是被转换成一个三位八进制数字,该数字数值等于相

应的十进制ASCII数值,然后前缀两个反斜扛.单引号(‘)和反斜扛字符0有白己特殊的逃逸序列.参

阅用户手册获取更多信息.PQescapeBytea执行这个操作,它只逃逸需要逃逸的最少的字符.

from参数指向需要逃逸的字串由第•个字符,from_]ength参数反映在这个二进制字串(那种

字节零既不必要也不计算在内的字串)里字符的个数.tolength参数应该是一个指向某个缓冲区的指

针,它的空间应该能够保存逃逸后的结果宇出K度.结果宇申K度不包括结果结尾的字节零.

PQescapeBytea返回一个from参数的二进制字串的逃逸后的版本,返回给调用者提供的缓冲区.返

回的字串已经把所有特殊的字符替换调了,这样他们就可以由PosigreSQL的字串文本分析器以及

bytea的输入函数正确地处理.同时还追加了一个结尾的字节零.那些必需包围在P。stgreSQL字串文

本周围的单引号不兑结果字串的部分.

PQunescapeBytea把一个二进制数据的逃逸后的字串表现形式转换成二进制数据-PQcscapeBy

tea的反作用.

unsignedchar*PQunescapeBytea(constunsignedchar*from,size_t*to_length):

from参数指向一个逃逸后的字串,比如PQgclvaluo从一个BYTEA字段返PI的.PQunescapcBytca

把它的字串表现形式转换成一进制形式,填充到一个缓冲区.它返回一个指向该缓冲区的指针,若为N

ILL则出错,缓冲区的尺寸放在to」englh里.该指针随后可以用做free(3)的参数.

1.3。4,检索SELECT的结果信息

*

PQntup1es返网查询结果里的元组(元组)个数.

intPQntup1es(constPGresuIt*res);

*

PQnfields返回查询结果里每个元组的数据域(字段)的个数.

intPQnfields(constPGresult*res);

*

PQfname返回与给出的数据域编号相关联的数据域(字段)的名称.数据域编号从0开始

char*PQfname(constPGresult*res,

intfield_index);

♦

PQfnumber返网与给出的数据域名称相关联的数据域(字段)的编号.

intPQfnumber(constPGresuit*res,

constchar*fie1d_name):

如果给出的名字不H配任何域,返回一L

*

PQftype返回与给定数据域编号关联的数据域类型.整数返回值是一个该类型的内部编码.数据域编号从0

开始.

OidPQftype(constPGresult*res,

intfieI<1_index);

你可以查询系统表pgtype以获取各种数据类型的名称和属性。内建的数据类型的OID在源码树的

src/include/catalog/pg_type.h文件里定义。

*

PQfmod返回与给定数据域编号相关联的类型相关的修正数据(??).数据域编号从0开始.

intPQfmod(constPGresult*res,

intfield_index);

*

PQfsize返回一个PGresult里面的一条元组的单独的一个数据域(字段)的值.元组和数据域编号从

0开始.

intPQfsize(constPGresu1t*res,

intfield_index);

PQfsize返回在数据库元组里面给该数据域分配的空间,换句话说就是该数据类型在服务器里的二进制

形式的大小(尺寸).如果该数据域是可变尺寸,返同-1.

*

PQbinaryTuples如果PGresult包含二进制元组数据时返回1,如果包含ASCII数据返回0.

intPQbinaryTupies(constPGresult*res):

目前,二进制元组数据只能从一个二进制游标里抽取数据的杳询返回.

1.3.5.检索SELECT结果数值

*

PQgetvalue返回一个PGresu1t里面一个元组单独的一个数据域(字段)的值.元组和数据域编号

从0开始.

char*PQgetvalue(constPGresult*res,

inttupnum,

intfield_num):

对大多数查询而言,PQgetvalue返回的值是一个表示字段值的空(NULL)结尾的字符串.但是如果

PQbinaryTuples()为1,PQgetvalue返回的值就是该类型在后端服务器内部的二进制表现形式

(但是不包括尺寸字一一如果数据域是变长的).这样,把数据转换成对应的C类型就是程序员的贵任

了.PQgelvalue返回的指针指向一个本身是PGresult结构的一部分的存储区域,我们不能更改它,

并且如果我们要在PGresult结构的生存期后还要使用它的话,我们必须明确地把该数值拷贝到其他存

储器中.

*

PQgetisnull测试一个数据域是否为空(NULL).元组和数据域编号从0开始.

intPQgetisnu11(constPGresult*res,

inttup_num,

intficldnum);

如果该域包含NULL,函数返回1,如果包含非空(non-null)值,返回0.(注意,对一个NULL数

据域,PQgetvalue将返回一个空字符串,不是一个空指针.)

*

PQ百etlength返回以字节计的数据域(字段)的长陵.元组和数据域编号从0开始.

intPQgct1cngth(constPGrcsult*res,

inttup_num,

intfic1d_num):

这是某一特定数据值的实际数据长度,也就是由PQgelvalue指向的对裂的尺寸.注意,对•于ASCII表

示的数值,这个尺寸与PQfsize报告的二进制尺寸无关.

*

PQprint向指定的输出流打印所有的元组和(可选的)字段名称.

voidPQprint(FILE*foul,/*outputstream*/

constPGresult*res.

constPQprintOpt♦po);

struet{

pqboo1header;/*printoutputfieldheadingsandrowcount♦/

pqboola1ign;/*fi11a1ignthefields*/

pqbooIstandard:/♦oldbraindeadformat*/

pqboolhtml3;/*outputhtmlIables*/

pqboolexpanded;/*expandtab1es*/

pqboolpager;/*usepagerforoutputifneeded*/

char*ficldScp;/*fieIdscparator*/

char*tableOpt;/*inSerttoHTMLtable..«*/

char*caption;/*HTMLcaption*/

char**fieldName:/*nullterminatedarrayofrep1acementfie1dnames*/

}PQprintOpt;

这个函数以前被psql用于打印查询结果,但是现在已经不用这个函数了,并且此函数不再有活跃的支

持。

1。3。6.检索非-SELECT结果信息

*

PQcmdStatus返回产生PGresuit的SQL命令的命令状态字符串.

char*PQcmdStatus(PGrcsuit*res);

*

PQcmdTuples返回被SQL命令影响的行的数量.

char*PQcmdTupIes(PGresult*res):

如果产生PGresult的SQL命令是INSERT,UPDATE或DELETE这里返回涉及行的行数.如果是

其他命令返向一个空字符串.

*

PQoidValue返回一个插入的元组的对象标识(0ID)一—如果SQL命令是INSERT.否则,返回

InvalidOid.

OidPQoidValue(constPGresult*res);

如果你包含了1ibpq头文件,那么Oid和常量InvalidOid的类型将被定义。他们都是某种整型

类型。

PQoidStatus返回一个被插入的元组的对象标识的字笔,如果SQL命令是INSERT。否则,返

回一个空字串

char*PQoidStatus(constPGresuIt*res);

因为有•了PQoidValue,我们不建议使用这个函数,而且它在线程里使用也是不安全的

PostgrcSQL数据库学习手册之1ibpq-C库一一异步查询处理(转)[flmore@]

1.4。异步查询处理

PQexec函数对简单的同步应用里提交命令已经是足够用的了.但是它却有几个主要的缺陷:

*

PQexcc等待命令结束.应用可能有其他工作要做(例如维护用户界面),这时它可不希望阻塞在这里等待返

回.

因为控制是藏在PQexec内部,前端很难取消掉正进行着的命令.(可以通过信号控制器进行,但没有别的方

法.)

PQexec只能返回一个PGresuIt结构.如果提交的命令字符串包含多个SQL命令,除了最后一个PGr

esuit以外都会被PQexec丢弃.

不想受到这些限制的应用可以改用下面的函数,这些函数也是构造PQexec的函数:PQsendQuery

和PQgetResu1to

使用这些(异步)功能以及PQputline和PQputnbytes的老•些的程序可能在等待数据发送给

后端时阻塞住,为解决这样的问题,增加了函数PQsetnonblocking.

旧应用可以忽略PQsetnonblocking的使用,维持原有的阻塞特征。新的程序可以利用NseIn。n

biocking获得与后端完全非阻塞的联接。

PQsetnonblocking把该联接的状态设置为非阻塞.

intPQsctnonblocking(PG20nn*conn,intarg)

如果arg为TRUE,把联接状态设置为非阻塞,如果arg为FALSE,把联接状态设置为阻塞.如果0

K返回0,如果错误返回一1.此函数将确保对

在非阻塞状态,调用PQputline,PQputnbytes,PQsendQuery和PQendcopy的时候不被阻塞,

而是如果需要再次它们时将是返回一个错误「而不是阻塞)。

当把一个数据库的联接设置为非阻塞的模式并且调用了PQexec,它将呼时把联接状态设置,为阻塞模式

直到PQexcc完成.

在不久的将来将有更多的libpq会设计成在PQSetn0nbloCking方式下是安全的。

PQisnonb1ocking返回数据南联接的阻塞状态.

intPQisnonblocking(constPGconn*conn)

如果联接设置为非阻塞状态,返向I,如果是阻塞状态返同04

*

PQsendQuery向服务器提交一个命令而不等待结果,如果查询成功发送则返回1,否则返回0.此时,可以

用PQerrorMessage获取关;失败的信息).

intPQsendQuery(PGconn*conn,

constchar*query);

在成功调用PQsendQuery后,调用PQgetResult一次或者多次获取结果.可以不再调用PQsend

Query(在同一次联接里)直到PQgelResulI返回NULL,表明命令完成.

PQgetResu1t等待从前面PQsendQuery调用返回的下一个结果,然后返回之.当查询结束并且没

有更多结果后返回NULL.

PGresuit*PQgetResult(PGconn*conn);

必须重且的调用PQgetResu1t,直到它返回NULL,表明该命令结束.(如果在没有活跃的命令时调用,

PQgetResu1t将只是立即返回VULL.)每个PQgeiResult返回的非NULL结果都应该用前面描

述的PGresult访问函数进行分析.不要忘了在结束分析后用PQc1ear释放每个结果对象.注意,

PQgetResu1t只是在有查询激活币口必须的返回数据还没有被PQconsumeInput读取时阻塞.

使用PQsendQuery和PQgetResult解决了PQcxec的一个问题:如果一个命令字符串包含多个

SQL命令,这些命令的结果可以独立的获得.(顺便说一句:这样就允许一种简单的重总处理模式,前端可以

处理一个查询的结果而后端可以仍然在处理同一命令字符串的后面的查询)但是,调用PQgetReSult

将仍然导致前端被阻塞住直到后端完成下一个SQL命令.这一点可以通过合理的使用下面三个函数来避

免:

PQconsumelnput如果存在后端来的输入可用,则使用之.

intPQconsumeInput(PGconn*conn);

PQconsumelnput通常返回1表明"没有错误",而返回0表明有某种错误发生,(同时设设PQ

errorMessage).注意这个结果并不表明实际上是否收集了数据.在调用PQconsumelnput之后,

应用可以检查PQisBusy和/或PQnotifies看一眼它们的状态是否改变.

PQconsumelnput叫以在应用还没有做好处埋结果或通知的情况卜被遍用.这个过程将诙取可用的数据

并且在一个缓冲区里保存它,这样导致一个seiectO读准备好标识的生成.这样应用就可以使用PQc

onsumelnput立即清掉select()条件,然后在空闲的时候桧查结果.

*

PQisBusy在查询忙的时候返回1,也就是说,PQgetResult将阻塞住等待输入.一个0的返回表明

这时调用PQgetResult可以确保不阻塞.

intPQisBusy(PGconn*conn):

PQisBusy本身将不会试图从后端读取数据:所以必须先调用PQconsumeInput,否则忙状态将永远不

会消除.

*

PQflush试图把任何正在排队的数据冲刷到后端,如果成功(或者发送队列为空)返回0,如果因某种原因

失败返回EOF。

intPQflush(PGconn*conn);

在一个非阻塞的联接调用sclcct()判断是否有响应到达之前需要调用一个PQflush.如果返回0

则保证了与后端的发送队列里面没有待发送的数据.只有使用了PQsetnonblocking的应用需要

这个。

PQsocket获取用于后端联接套接字的文件描述符号.一个有效的描述符应该是〉=0:一个一1表

明当前没有打开与后端的暇接.

intBQsocket(constconn*conn);

PQs。eket应该用于获取准备调用select()的后端套接字描述符.这就允许一个应用使用阻塞的联

接等待后端的响应或者其他条件,如果select()的结果表明可以从后端套接字读取数据,那么应该

调用PQconsumeInput读取数据;之后,,PQisBusy,PQgetResult,和/或PQnotifies可用

于处理返回信息.

非阻塞的联接(那些使用了PQseinonblocking的联接)在PQflush返回0之前,(这表明没有

数据缓冲着等待发送给后端)不应该使用select().

一个使用这些函数的典型的前端将有一个主循环使用select()等待所有它必须处理的条件.其中一个

条件将会是后端来的数据已准备好,从select。的角度来看就是PQsockct标识的文件描述符上已

经有可读取的数据.当主循环侦测到输入准备好,它将调用PQconsumeInput读取输入.然后可以调用PQ

isBusy返回faIse(0)后面可以跟着PQgetResult。同样它(用户应用)可以调用PQnotifies

测NOTIFY信息(参阅下面的“异步通知”).例子程序节里面给出了一个例子程序.

个使用PQsendQuc>y/PQgecReSu1t的前端同样也可以试图取消一个正在被后端处理的命令.

PQrcqucstCanccl要求PostgrcSQL放弃处理当前命令.

intPQrequcstCancel(PGconn*conn);

如果取消的请求成功发送,返回值是1,否则是0.(如果为假,PQerrorMessage会告之为什么.)不

过,取消请求的成功发送将不保证请求将产牛•作用.不管PQrequestCancel的返回值是什么,应用

都必须继续使用PQgetResult进行通常的后续的结果读取工作.如果取消动作生效,当前的命令将提前

退出并返回•个错误结果.如果取消动作失败(也就是后端已经处理完

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论