首页 > 数据库 >数据库编程接口Libpq 2

数据库编程接口Libpq 2

时间:2023-01-02 15:06:02浏览次数:56  
标签:返回 const 函数 int Libpq 数据库 编程 服务器 执行


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表示请求没有成功地传给服务器。函数执行成功以后,调用​​P​​​​Q​​​​getResult​​​​确定准备好的语句是否被成功地创建。​

 

​PQsendQueryPrepared​

 

给服务发送一个执行一条准备好的语句的请求,然后立即返回。

 

int PQsendQueryPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);

它的参数与​​P​​​​Q​​​​execPrepared​​​​是一样的。​


​PQsendDescribePrepared​

给服务发送一个得到一条准备好的语句的信息的请求,然后立即返回。

 

int PQsendDescribePrepared(PGconn *conn, const char *stmtName);

 

这个函数的参数与​​P​​​​Q​​​​describePrepared​​​​是一样的。返回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表示执行失败(调用​​​​P​​​​Q​​​​rrorMessage​​​​得到详细的错误信息)。​

 

​PQisBusy​

返回1表示发送给服务器的命令正在执行,如果调用​​P​​​​Q​​​​getResult​​​​,会处于等待的状态。​​​返回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);


      在非阻塞的连接上发送了任何命令给数据库以后,都应该调用​​P​​​​Q​​​​flush​​​​。如果它返回1,应该等待一段时间后再调用​​​​PQflush​​​​,直到它返回0。​

1.5 终止正在执行的查询

客户端可以发送请求给服务器,要求终止正在被服务器执行的命令。本节介绍的函数就实现了这样的功能。


PQgetCancel


创建一个数据结构,这个数据结构包含终止正在被服务器执行的命令需要的所有信息。


PGcancel *PQgetCancel(PGconn *conn);

函数返回一个指向PQcancel对象的指针。如果参数conn的值是NULL或者指向一个非法的连接,函数将返回NULL。可以将函数返回的指针作为参数传给PQcancel和PQfreeCancel。


PQfreeCancel


释放PQgetCancel创建的PQcancel对象占用的内存。


void PQfreeCancel(PGcancel *cancel);


PQcancel

要求服务器终止正在执行的命令。


int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);

返回值是1表示请求成功地传递给服务器。返回值是0表示请求没有被成功地传递给服务器。如果函数返回0,参数errbuf指向的缓冲区中将存有具体的错误信息。参数errbufsize指明errbuf指向的缓冲区的大小,单位是字节,推荐值是256。


即使请求被成功地发送给服务器,也不代表请求会生效。如果请求被成功地执行,正在执行的命令会被终止,并给客户端返回一个错误结果。如果请求没有被成功地执行(因为被终止的命令已经执行结束),服务器不会返回任何结果给客户端。


可以在信号处理程序(signal handler)内部调用PQcancel,errbuf必须是信号处理程序的局部变量。


1.5 终止正在执行的查询

客户端可以发送请求给服务器,要求终止正在被服务器执行的命令。本节介绍的函数就实现了这样的功能。


PQgetCancel


创建一个数据结构,这个数据结构包含终止正在被服务器执行的命令需要的所有信息。


PGcancel *PQgetCancel(PGconn *conn);

函数返回一个指向PQcancel对象的指针。如果参数conn的值是NULL或者指向一个非法的连接,函数将返回NULL。可以将函数返回的指针作为参数传给PQcancel和PQfreeCancel。


PQfreeCancel


释放PQgetCancel创建的PQcancel对象占用的内存。


void PQfreeCancel(PGcancel *cancel);


PQcancel

要求服务器终止正在执行的命令。


int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);

返回值是1表示请求成功地传递给服务器。返回值是0表示请求没有被成功地传递给服务器。如果函数返回0,参数errbuf指向的缓冲区中将存有具体的错误信息。参数errbufsize指明errbuf指向的缓冲区的大小,单位是字节,推荐值是256。


即使请求被成功地发送给服务器,也不代表请求会生效。如果请求被成功地执行,正在执行的命令会被终止,并给客户端返回一个错误结果。如果请求没有被成功地执行(因为被终止的命令已经执行结束),服务器不会返回任何结果给客户端。


可以在信号处理程序(signal handler)内部调用PQcancel,errbuf必须是信号处理程序的局部变量。

1.6 注意(Notice)消息处理

服务器产生的注意(Notice)和警告(Warning) 消息不会被执行查询的函数(如PQexec)返回。这些消息被传递给客户端的注意消息处理函数,注意消息处理函数执行完以后,客户端会继续执行其它的操作。Libpq提供的默认的注意消息处理函数只是将注意和警告消息输出到stderr,应用程序也可以使用自己定义的消息处理函数。



实际上,客户端收到服务器产生的注意和警告消息以后,会首先调用一个注意消息接收函数,然后再调用一个注意消息处理函数。默认的注意消息接收函数格式化收到的注意消息,然后把格式化以后的消息发给注意消息处理函数。默认的消息处理函数将输出收到的格式化以后的消息。应用程序可以只提供自己的注意消息接收函数,在这个函数里完成所有的工作。



应用程序可以使用函数PQnoticeReceiver来注册和查询注意消息接受函数,使用函数PQsetNoticeProcessor来注册和查询注意消息处理函数。


typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);

PQnoticeReceiver

PQsetNoticeReceiver(PGconn *conn,

PQnoticeReceiver proc,

void *arg);

typedef void (*PQnoticeProcessor) (void *arg, const char *message);

PQnoticeProcessor

PQsetNoticeProcessor(PGconn *conn,

PQnoticeProcessor proc,

void *arg);


这两个函数都返回指向以前使用的注意消息接收函数或注意消息处理函数的指针,并且设置新的注意消息接收函数或注意消息处理函数。如果参数PQnoticeReceiver或PQnoticeProcessor的值为NULL,这两个函数什么都不会做,只是返回指向当前使用的注意消息接收函数或注意消息处理函数的指针。



只要客户端收到服务器发送过来的注意或警告消息,或者libpq自身产生的注意或警告消息,注意消息接收函数就会被调用。注意消息接收函数使用PQresultErrorField和 PQresultErrorMessage来得到消息的细节。



默认的注意消息接收函数调用PQresultErrorMessage得到具体的消息的内容,然后把它传给注意消息处理函数。



默认的注意消息处理函数的定义如下:

static voiddefaultNoticeProcessor(void *arg, const char *message){

fprintf(stderr, "%s", message);}


注意消息接收函数和注意消息处理函数与PGconn对象相关,不同的数据库连接可以设置不同的注意消息接收函数和注意消息处理函数。

标签:返回,const,函数,int,Libpq,数据库,编程,服务器,执行
From: https://blog.51cto.com/u_15747257/5983700

相关文章

  • PostgreSQL 数据库集群和PL/Proxy配置安装指南
    ​​PL/Proxy​​​和​​PostgreSQL​​​集群的结构关系可以用下图清楚地表示,对PL/Proxy和PostgreSQL集群还不太了解的朋友可以看​​SkypePlansforPostgreSQLtoScal......
  • Java编程技术期末复习总结
    Java编程技术期末复习总结一、Java编程基础下列软件包中,不需要使用import指令就可直接使用的是____。A.java.langB.java.textC.java.sqlD.java.utilA在java......
  • 计算机编程基础-编程语言,计算机基础
    计算机编程基础目录计算机编程基础1.编程语言1.1编程1.2计算机语言1.3编程语言1.4翻译器2.计算机基础2.1计算机组成2.1计算机组成2.2数据存储2.3数据存储单位2......
  • 学习ASP.NET Core Blazor编程系列十九——文件上传(下)
    学习ASP.NETCoreBlazor编程系列文章之目录学习ASP.NETCoreBlazor编程系列一——综述学习ASP.NETCoreBlazor编程系列二——第一个Blazor应用程序(上)学习A......
  • mysql数据库的分区与分表(概念性说明)
    为什么要分区或者分表分区、分表都是解决数据量大,查询数据慢的主要手段。正常情况下一个innodb表,在没有分区分表情况下。在数据库文件数据中,它是有一个存储表结构的.frm文件......
  • 极客编程python入门-多进程
    多进程在Python程序中轻松创建子进程:importosprint('Process(%s)start...'%os.getpid())#OnlyworksonUnix/Linux/Mac:pid=os.fork()ifpid==0:print('Iam......
  • STC15 MCU 串口编程 proteus 仿真 SDCC51
    1.STC单片机接口比传统的51单片机多得多,学起来更有意思。据说这种单片机得实际使用也很多,价格便宜,可以用来DIY。2.KEIL是比较流行的编程工具,有点大,还需要license之类的,对......
  • SpringBoot中使用JDBC(扩展:关于java中的jdbc、数据库驱动、数据库连接池的学习与理解)
    SpringBoot中使用JDBC:https://huaweicloud.csdn.net/63876ea0dacf622b8df8bf7d.html?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7E......
  • 【win编程0003】- 动态库
     动态链接库(dynamiclinklibrary)介绍代码放到exe中,肯定会造成磁盘冗余;电脑ABCD四个软件,lib加入到代码中不是在编译期进入的,而是在运行期(A进程启动,把dll加入到A进程......
  • 狂神说Go语言—并发编程
    聊聊进程、线程、协程多线程上方左图所示:在主线程中为main方法左图的右边为test方法,在main方法中调用test方法,mian方法执行就会先去执行test方法,执行完后再回到main......