目录
本文参考《PostgreSQL 15.7 手册之客户端接口》。
一、环境
名称 | 描述 |
PG | PostgreSQL 16.3 |
CPU | Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz |
OS | CentOS Linux release 7.9.2009 (Core) |
二、介绍
libpq是应用程序员使用PostgreSQL的C接口。libpq是一个库函数的集合,它们允许客户端程序传递查询给PostgreSQL后端服务器并且接收这些查询的结果。
libpq也是很多其他PostgreSQL应用接口的底层引擎,包括为 C++、Perl、Python、Tcl 和 ECPG编写的接口。
三、函数
libpq接口函数较多,本文只介绍自己封装用到的。
1、PQsetdbLogin
(1)作用
开启一个到数据库服务器的新连接。
(2)声明
PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
(3)参数介绍
参数名 | 描述 |
pghost | IP地址 |
pgport | 数据库端口号 |
pgoptions | 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off 会将会话的geqo 参数的值设置为off 。 此字符串中的空格被视为分隔命令行参数,除非用反斜杠(\ )转义;写\\ 表示字面上的反斜杠。 |
pgtty | 已被弃用 |
dbName | 数据库名 |
login | 数据库用户名 |
pwd | 数据库密码 |
(4)检测成功与否
见PQstatus函数。
2、PQfinish
(1)作用
关闭与服务器的连接。同时释放PGconn
对象使用的内存。
注意,即使与服务器的连接尝试失败(由PQstatus指示),应用也应当调用PQfinish来释放PGconn
对象使用的内存。不能在调用PQfinish之后再使用PGconn
指针。
(2)声明
void PQfinish(PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)检测成功与否
无
3、PQreset
(1)作用
重置与服务器的通讯通道。
(2)声明
void PQreset(PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)检测成功与否
无
4、PQstatus
(1)作用
返回该连接的状态。
(2)声明
ConnStatusType PQstatus(const PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)返回值
宏 | 描述 |
CONNECTION_OK | 数据库连接状态正常 |
CONNECTION_BAD | 数据库连接状态非正常 |
CONNECTION_STARTED | 等待连接建立 |
CONNECTION_MADE | 连接正常;等待发送 |
CONNECTION_AWAITING_RESPONSE | 等待来自postmaster的响应 |
CONNECTION_AUTH_OK | 收到认证信息;等待后端启动 |
CONNECTION_SETENV | 此状态不再使用 |
CONNECTION_SSL_STARTUP | 正在协商SSL |
CONNECTION_NEEDED | 内部状态:需要connect() |
CONNECTION_CHECK_WRITABLE | 检查会话是否为读写 |
CONNECTION_CONSUME | 消耗任何额外的消息 |
CONNECTION_GSS_STARTUP | 正在协商GSSAPI |
CONNECTION_CHECK_TARGET | 检查目标服务器属性 |
CONNECTION_CHECK_STANDBY | 检查服务器是否处于备用模式 |
5、PQserverVersion
(1)作用
返回一个表示服务器版本的整数。
(2)声明
int PQserverVersion(const PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)检测成功与否
无。
6、PQerrorMessage
(1)作用
返回连接上的一个操作最近产生的错误消息。
几乎所有的libpq在失败时都会为PQerrorMessage设置一个消息。 注意按照libpq习惯,一个非空PQerrorMessage结果由多行构成,并且将包括一个尾部新行。 调用者不应该直接释放结果。当相关的PGconn
句柄被传递给PQfinish时,它将被释放。在PGconn
结构上的多个操作之间,不能指望结果字符串会保持不变。
(2)声明
char *PQerrorMessage(const PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)检测成功与否
无
7、PQbackendPID
(1)作用
返回处理这个连接的后端进程的进程ID(PID)。
后端PID有助于调试目的并且可用于与NOTIFY
消息(它包括发出提示的后端进程的PID)进行比较。注意PID属于一个在数据库服务器主机上执行的进程,而不是本地主机进程!
(2)声明
int PQbackendPID(const PGconn *conn)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
(4)检测成功与否
无
8、PQprepare
(1)作用
提交一个请求用给定参数创建一个预备语句并且等待完成。
PQprepare创建一个后面会由PQexecPrepared执行的预备语句。 这个特性允许命令被反复执行而无需每次都进行解析和规划。
该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1、$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 如果paramTypes是NULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见PQdescribePrepared)。
正如PQexec一样,结果通常是一个PGresult对象,其内容代表服务器端成功或失败。 一个空结果表示内存不足或者根本无法发送命令。关于错误的更多信息请见PQerrorMessage。
用于PQexecPrepared的预备语句也能通过执行 SQL PREPARE语句来创建。 还有,尽管没有libpq函数来删除一个预备语句,SQL DEALLOCATE语句可被用于此目的。
(2)声明
PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体指针 |
stmtName | 语句句柄名 |
query | 执行语句 |
nParams | 参数个数 |
paramTypes | 参数类型 |
(4)检测成功与否
见PQresultStatus函数。
9、PQresultStatus
(1)作用
返回该命令的结果状态。
如果结果状态是PGRES_TUPLES_OK
或者PGRES_SINGLE_TUPLE
,那么下面所描述的函数能被用来检索该查询所返回的行。注意,一个恰好检索零行的SELECT
命令仍然会显示PGRES_TUPLES_OK
。PGRES_COMMAND_OK
用于从不返回行的命令(不带RETURNING
子句的INSERT
或者UPDATE
等)。一个PGRES_EMPTY_QUERY
可能表示客户端软件中的一个缺陷。
一个状态为PGRES_NONFATAL_ERROR
的结果将不会被PQexec或者其他查询执行函数直接返回,这类结果将被传递给提示处理器。
(2)声明
ExecStatusType PQresultStatus(const PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)返回值
宏 | 描述 |
PGRES_EMPTY_QUERY | 发送给服务器的字符串为空。 |
PGRES_COMMAND_OK | 一个不返回数据的命令成功完成。 |
PGRES_TUPLES_OK | 一个返回数据的命令(例如SELECT 或者SHOW )成功完成。 |
PGRES_COPY_OUT | 从服务器复制出数据的传输开始。 |
PGRES_COPY_IN | 复制数据到服务器的传输开始。 |
PGRES_BAD_RESPONSE | 从后端收到意外响应 |
PGRES_NONFATAL_ERROR | 发生了一次非致命错误(一个提示或警告)。 |
PGRES_FATAL_ERROR | 发生了一次致命错误。 |
PGRES_COPY_BOTH | 向服务器复制数据/从服务器复制数据的传输开始。这个特性当前只被用于流复制,因此这个状态应该不会在普通应用中出现。 |
PGRES_SINGLE_TUPLE | PGresult 包含来自于当前命令的一个单一结果元组。这个状态只在查询选择了单一行模式时发生 |
PGRES_PIPELINE_SYNC | PGresult 表示管道模式中的同步点,由PQpipelineSync请求。 此状态仅在选择管道模式时发生。 |
PGRES_PIPELINE_ABORTED | PGresult 表示从服务器接收到错误的管道。 PQgetResult 必须被重复调用,并且每次它都会返回这个状态码,直到当前管道结束,此时它将返回PGRES_PIPELINE_SYNC ,并且正常的处理可以继续。 |
10、PQclear
(1)作用
释放与一个PGresult
相关的内存。
每一个命令结果不再需要时应该用PQclear释放。
你可以按照需要保留PGresult对象,当你发出一个新命令时它也不会消失,甚至关闭连接时也不会消失。 要去掉它,你必须调用PQclear。没有这样做将会导致在应用中的内存泄露。
(2)声明
void PQclear(PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)检测成功与否
无
11、PQntuples
(1)作用
返回查询结果中的行(元组)数(注意,PGresult
对象被限制为不超过INT_MAX
行,因此一个int
结果就足够了)。
(2)声明
int PQntuples(const PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)检测成功与否
无
12、PQnfields
(1)作用
返回查询结果中每一行的列(域)数。
(2)声明
int PQnfields(const PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)检测成功与否
无
13、PQfname
(1)作用
返回与给定列号相关联的列名。
调用者不应该直接释放该结果。它将在相关的PGresult句柄被传递给PQclear之后被释放。
(2)声明
char *PQfname(const PGresult *res, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
14、PQftable
(1)作用
返回给定列从中取出的表的 OID。列号从 0 开始。
如果列号超出范围或者指定的列不是对一个表列的简单引用时,返回InvalidOid
。 你可以查询系统表pg_class
来确定究竟是哪个表被引用。
当你包括libpq头文件,类型oid
以及常数InvalidOid
将被定义。它们将都是某种整数类型。
(2)声明
Oid PQftable(const PGresult *res, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
15、PQftype
(1)作用
返回与给定列号相关联的数据类型。被返回的整数是该类型的内部 OID 号。列号从 0 开始。
你可以查询系统表pg_type
来得到多个数据类型的名字和属性。 内建数据类型的OID被定义在PostgreSQL安装的include
目录中的catalog/pg_type_d.h
文件中。
(2)声明
Oid PQftype(const PGresult *res, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
16、PQfmod
(1)作用
返回与给定列号相关联的列的修饰符类型。列号从 0 开始。
修饰符值的解释是与类型相关的,它们通常指示精度或尺寸限制。值 -1 被用来指示“没有信息可用”。大部分的数据类型不适用修饰符,在那种情况中值总是 -1。
(2)声明
int PQfmod(const PGresult *res, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
17、PQfsize
(1)作用
返回与给定列号相关的列的尺寸(以字节计)。列号从 0 开始。
PQfsize返回在一个数据库行中为这个列分配的空间,换句话说是服务器对该数据类型的内部表示的尺寸(因此,它对客户端并不是真地非常有用)。一个负值指示该数据类型是变长的。
(2)声明
int PQfsize(const PGresult *res, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
18、PQgetvalue
(1)作用
返回一个PGresult
的一行的单一域值。行和列号从 0 开始。调用者不应该直接释放该结果。 它将在相关的PGresult
句柄被传递给PQclear之后被释放。
对于文本格式的数据,PQgetvalue返回的值是该域值的一种空值结束的字符串表示。对于二进制格式的数据,该值是由该数据类型的typsend
和typreceive
函数决定的二进制表示(在这种情况下该值实际上也跟随着一个零字节,但是这通常没有用处,因为该值很可能包含嵌入的空)。
如果该域值为空,则返回一个空串。关于区分空值和空字符串值请见PQgetisnull。
PQgetvalue返回的指针指向作为PGresult
结构一部分的存储。我们不应该修改它指向的数据,并且如果要在超过PGresult
结构本身的生命期之外使用它,我们必须显式地把该数据拷贝到其他存储中。
(2)声明
char *PQgetvalue(const PGresult *res, int tup_num, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
tup_num | 行号,从 0 开始。 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
19、PQgetisnull
(1)作用
测试一个域是否为空值。行号和列号从 0 开始。
如果该域是空,这个函数返回 1。如果它包含一个非空值,则返回 0(注意PQgetvalue将为一个空域返回一个空串,不是一个空指针)。
(2)声明
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
tup_num | 行号,从 0 开始。 |
field_num | 列号,从 0 开始。 |
(4)检测成功与否
无
20、PQnparams
(1)作用
返回一个预备语句的参数数量。
只有在查看PQdescribePrepared的结果时,这个函数才有用。对于其他类型的查询,它将返回零。
(2)声明
int PQnparams(const PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)检测成功与否
无
21、PQparamtype
(1)作用
返回所指示的语句参数的数据类型。参数号从 0 开始。
只有在查看PQdescribePrepared的结果时,这个函数才有用。对于其他类型的查询,它将返回零。
(2)声明
Oid PQparamtype(const PGresult *res, int param_num)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
param_num | 参数号,从 0 开始。 |
(4)检测成功与否
无
22、PQcmdTuples
(1)作用
返回受该 SQL 命令影响的行数。
该函数返回一个字符串,其中包含由生成PGresult
的SQL语句影响的行数。 该函数只能在执行SELECT
、CREATE TABLE AS
、 INSERT
、UPDATE
、DELETE
、 MERGE
、MOVE
、FETCH
或COPY
语句, 或包含INSERT
、UPDATE
、DELETE
或MERGE
语句的预处理查询的EXECUTE
之后使用。 如果生成PGresult
的命令是其他任何命令,PQcmdTuples将返回一个空字符串。 调用者不应直接释放返回值。当关联的PGresult
句柄传递给PQclear时,它将被释放。
(2)声明
char *PQcmdTuples(PGresult *res)
(3)参数介绍
参数名 | 描述 |
res | 结构体指针 |
(4)检测成功与否
无
23、PQexecPrepared
(1)作用
发送一个请求来执行一个带有给定参数的预处理语句,并等待结果。
PQexecPrepared类似于PQexecParams, 但要执行的命令是通过指定先前准备好的语句来指定,而不是提供查询字符串。 此功能允许重复使用的命令只被解析和计划一次,而不是每次执行时都要进行。 该语句必须在当前会话中先前准备好。
参数与PQexecParams相同,只是给出了预处理语句的名称而不是查询字符串, 并且paramTypes[]
参数不存在(因为在创建预处理语句时已确定了参数类型)。
(2)声明
PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
(3)参数介绍
参数名 | 描述 |
conn | 数据库连接结构体 |
stmtName | 句柄名 |
nParams | 参数个数 |
paramValues | 参数值 |
paramLengths | 参数长度 |
paramFormats | 指定参数是否为文本(在参数相应的数组项中放一个零)或二进制(在参数相应的数组项中放一个一)。如果该数组指针为空,那么所有参数都会被假定为文本串。 以二进制格式传递的值要求后端所期待的内部表示形式的知识。例如,整数必须以网络字节序被传递。传递numeric值要求关于服务器存储格式的知识,正如src/backend/utils/adt/numeric.c::numeric_send()以及src/backend/utils/adt/numeric.c::numeric_recv()中所实现的。 |
resultFormat | 指定零来得到文本格式的结果,或者指定一来得到二进制格式的结果(目前没有规定要求以不同格式得到不同的结果列,尽管在底层协议中这是可以实现的)。 |
(4)检测成功与否
无
四、封装Demo测试
1、Demo
#include "PgDb.h"
#define TEST_PARAM_NUMS 100
#define TEST_PARAM_DATA_LEN 30
#define TEST_DATA_ROWS 3
#define TEST_DATA_COLS 8
#define TEST_DATA_SIZE 50
#define TEST_DELIMITER '|'
#define TEST_NULL ""
#define TEST_QUTO '"'
#define TEST_ESCAPE '\\'
Status main()
{
LOG_LEVEL = Debug;
MyPgSt *PgSt = NULL;
PgConnSt PgConnInfo = PG_CONN_ST_INIT("192.168.142.12","5432","","czg","postgres","postgres","UTF8");
CopyStr *Sql = NULL;
int ParamNums;
char **ParamValues = (char **)MyMalloc(sizeof(char *) * TEST_PARAM_NUMS);
int i;
int j;
Status MyStatus = FAIL_FLAG;
for ( ParamNums = 0; ParamNums < TEST_PARAM_NUMS; ParamNums++)
{
ParamValues[ParamNums] = (char *)MyMalloc(sizeof(char) * TEST_PARAM_DATA_LEN);
}
InitCopyStr(&Sql);
PgInit(&PgSt);
if (PgConn(&PgConnInfo,PgSt) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*同步函数测试*/
/*开启事务,也就相当于非自动提交*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"BEGIN;\n");
if (PG_EXEC_SQL(PgSt,Sql->String) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*执行查询SQL文本DDL*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"\n\
CREATE TABLE IF NOT EXISTS PUBLIC.TESTTAB(\n\
A SERIAL PRIMARY KEY ,\n\
B DOUBLE PRECISION ,\n\
C CHARACTER VARYING(100) ,\n\
D TEXT ,\n\
E BYTEA ,\n\
F BYTEA ,\n\
G DATE ,\n\
H TIMESTAMP WITHOUT TIME ZONE ,\n\
I NUMERIC(10,2) );\n");
if (PG_EXEC_SQL(PgSt,Sql->String) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*执行COPY文本*/
PG_COPY_SPLICING(Sql,"PUBLIC","TESTTAB","B,C,D,E,F,G,H,I","FROM","'/home/postgres/PgData.txt'","CSV",TEST_DELIMITER,TEST_NULL,TEST_QUTO,TEST_ESCAPE);
if (PG_EXEC_SQL(PgSt,Sql->String) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*执行查询SQL文本DQL*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"SELECT * FROM PUBLIC.TESTTAB ORDER BY A DESC LIMIT 10;\n");
if (PG_EXEC_SQL(PgSt,Sql->String) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
PgResDataPrint(PgSt, Debug);
PG_DQL_FREE(PgSt);
/*执行插入SQL文本*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES(2.1,'LXG''ZXJ|CLX','HAHHAHAH','AAAAAA','BBBBBBBBBBBB','2024-08-19','2024-08-19',8);\n");
if (PG_EXEC_SQL(PgSt,Sql->String) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*执行查询SQL绑定变量方式*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;\n");
ParamNums = 1;
strcpy(ParamValues[0],"1.1");
if (PG_EXEC_SQL_PREPARE(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
PgResDataPrint(PgSt, Debug);
PG_DQL_FREE(PgSt);
/*执行查询SQL绑定变量方式,复用上一次的解析结果*/
ParamNums = 1;
strcpy(ParamValues[0],"3.1");
if (PG_EXEC_SQL_REUSE(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
PgResDataPrint(PgSt, Debug);
PG_DQL_FREE(PgSt);
/*执行插入SQL绑定变量方式*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES($1,$2,$3,$4,$5,$6,$7,$8),($9,$10,$11,$12,$13,$14,$15,$16);\n");
ParamNums = 16;
const char * const ParamValues3[] = {"4.1","LXG''ZXJ|CLX","HAHHAHAH","AAAAAA","BBBBBBBBBBBB","2024-08-19","2024-08-19","8","5.1","LXG''ZXJ|CLX","HAHHAHAH","AAAAAA","BBBBBBBBBBBB","2024-08-19","2024-08-19","8"};
for ( i = 0; i < ParamNums; i++)
{
strcpy(ParamValues[i],ParamValues3[i]);
}
if (PG_EXEC_SQL_PREPARE(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*执行插入SQL绑定变量方式,复用解析*/
ParamNums = 16;
const char * const ParamValues4[] = {"6.1","LXG''ZXJ|CLX","HAHHAHAH","AAAAAA","BBBBBBBBBBBB","2024-08-19","2024-08-19","8","7.1","LXG''ZXJ|CLX","HAHHAHAH","AAAAAA","BBBBBBBBBBBB","2024-08-19","2024-08-19","8"};
for ( i = 0; i < ParamNums; i++)
{
strcpy(ParamValues[i],ParamValues4[i]);
}
if (PG_EXEC_SQL_REUSE(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues) != SUCCESS_FLAG)
{
goto ERR_PHASE;
}
/*异步函数测试*/
/*执行插入SQL文本*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES(2.1,'LXG''ZXJ|CLX','HAHHAHAH','AAAAAA','BBBBBBBBBBBB','2024-08-19','2024-08-19',8);\n");
MyStatus = PG_EXEC_SQL_ASYNC(PgSt,Sql->String);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*执行查询SQL绑定变量方式*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;\n");
ParamNums = 1;
strcpy(ParamValues[0],"1.1");
MyStatus = PG_EXEC_SQL_PREPARE_ASYNC(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
else if (MyStatus == SUCCESS_FLAG)
{
PgResDataPrintAsync(PgSt, Debug);
}
/*执行查询SQL绑定变量方式,复用解析*/
ParamNums = 1;
strcpy(ParamValues[0],"3.1");
MyStatus = PG_EXEC_SQL_REUSE_ASYNC(PgSt,Sql->String,ParamNums,(const char * const*)ParamValues);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
else if (MyStatus == SUCCESS_FLAG)
{
PgResDataPrintAsync(PgSt, Debug);
}
/*执行COPY文本*/
PG_COPY_SPLICING(Sql,"PUBLIC","TESTTAB","B,C,D,E,F,G,H,I","FROM","'/home/postgres/PgData.txt'","CSV",TEST_DELIMITER,TEST_NULL,TEST_QUTO,TEST_ESCAPE);
MyStatus = PG_EXEC_SQL_ASYNC(PgSt,Sql->String);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*执行COPY IN文本,目前只有PG_EXEC_SQL_ASYNC支持*/
/*\进行转义,例如:"1LXG'ZXJ|\"CLX",这只是C定义的时候的时候需要。*/
/*\进行转义,例如:"\\x414141414141",第一个\是C定义的时候的时候需要。*/
char CopyData[TEST_DATA_ROWS][TEST_DATA_COLS][TEST_DATA_SIZE] = \
{{"18.1","1LXG'ZXJ|\"CLX","HAHHAHAH","\\x414141414141","","2024-08-19","2024-08-19 00:00:00","8.00"},
{"18.1","2LXG'ZXJ|\"CLX","HAHHAHAH","\\x414141414141","\\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"},
{"18.1","","HAHHAHAH","","\\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"}};
/*测试demo,Data就不释放内存了,由系统自动释放,偷个懒。*/
char ***Data = (char ***)MyMalloc(sizeof(char **) * TEST_DATA_ROWS);
for ( i = 0; i < TEST_DATA_ROWS; i++)
{
Data[i] = (char **)MyMalloc(sizeof(char *) * TEST_DATA_COLS);
for ( j = 0; j < TEST_DATA_COLS; j++)
{
Data[i][j] = (char *)MyMalloc(sizeof(char) * TEST_DATA_SIZE);
strcpy(Data[i][j],CopyData[i][j]);
}
}
Oid ColTypeArray[TEST_DATA_COLS] = {701,1043,25,17,17,1082,1114,1700};
PG_COPY_SPLICING(Sql,"PUBLIC","TESTTAB","B,C,D,E,F,G,H,I","FROM","STDIN","CSV",TEST_DELIMITER,TEST_NULL,TEST_QUTO,TEST_ESCAPE);
MyStatus = PG_EXEC_SQL_ASYNC(PgSt,Sql->String);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
MyStatus = PgCopyIn(PgSt,Data,TEST_DATA_ROWS,TEST_DATA_COLS,TEST_DELIMITER,TEST_NULL,TEST_QUTO,TEST_ESCAPE,ColTypeArray);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
MyStatus = PgCopyInEnd(PgSt);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*执行提交SQL文本*/
ClearCopyStr(Sql,0);
ExecCopyStr(Sql,"COMMIT;\n");
MyStatus = PG_EXEC_SQL_ASYNC(PgSt,Sql->String);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*测试某库某模式下所有主键表获取*/
MyStatus = PgSchemaPkGet(PgSt,"czg","public");
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
else if (MyStatus == SUCCESS_FLAG)
{
PgResDataPrintAsync(PgSt, Debug);
}
/*测试某库某模式下主键表获取*/
MyStatus = PgTabPkGet(PgSt,"czg","public","testtab");
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
else if (MyStatus == SUCCESS_FLAG)
{
PgResDataPrintAsync(PgSt, Debug);
}
/*测试PG根据主键切分表,返回主键最大值,最小值,步长等信息。*/
PgPkSplitSt PkSplitInfo;
MyStatus = PgTabPkSplit(PgSt,"a","public","testtab","",6,&PkSplitInfo);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*测试PG计算单表条数。*/
MyStatus = PgCntSingleTab(PgSt,"public","testtab","",&i);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*测试PG导出文本。*/
PG_COPY_SPLICING(Sql,"PUBLIC","TESTTAB","B,C,D,E,F,G,H,I","TO","'/home/postgres/PgDataOut.txt'","CSV",TEST_DELIMITER,TEST_NULL,TEST_QUTO,TEST_ESCAPE);
MyStatus = PG_EXEC_SQL_ASYNC(PgSt,Sql->String);
if (MyStatus == FAIL_FLAG)
{
goto ERR_PHASE;
}
/*释放内存资源*/
ERR_PHASE:
DestroyCopyStr(&Sql);
PgDestroy(&PgSt);
for ( ParamNums = 0; ParamNums < TEST_PARAM_NUMS; ParamNums++)
{
free(ParamValues[ParamNums]);
ParamValues[ParamNums] = NULL;
}
free(ParamValues);
ParamValues = NULL;
return MyStatus;
}
2、测试效果
下一次和大家分享一下异步模式,Demo中对异步命令处理进行封装,获取元数据阶段是同步的,执行SQL,获取查询数据等都是异步处理的。
[gbase@czg2 Exec]$ ./TestPg
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgInit : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT PG_CATALOG.SET_CONFIG('search_path', '', false);
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.001 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 1
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 set_config 25 -1 -1 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgParamSet : OK, ParamName : 'search_path', ParamVal : '', ParamLv : 0
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgConn : OK, Host : '192.168.142.12', User : 'postgres', Db : 'czg', Port : '5432', Encode : 'UTF8', BackendPid : 33856, PqlibV : 160003, PgV : 160003, PqThrdSafe : 1.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : BEGIN;
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.000 s, Affect 0 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query :
CREATE TABLE IF NOT EXISTS PUBLIC.TESTTAB(
A SERIAL PRIMARY KEY ,
B DOUBLE PRECISION ,
C CHARACTER VARYING(100) ,
D TEXT ,
E BYTEA ,
F BYTEA ,
G DATE ,
H TIMESTAMP WITHOUT TIME ZONE ,
I NUMERIC(10,2) );
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Warn ]-MyNoticeProcessor : OK, NOTICE: 42P07: relation "testtab" already exists, skipping
LOCATION: transformCreateStmt, parse_utilcmd.c:207
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.001 s, Affect 0 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query :
COPY PUBLIC.TESTTAB(B,C,D,E,F,G,H,I)
FROM '/home/postgres/PgData.txt'
WITH(
FORMAT CSV,
DELIMITER '|',
NULL '',
QUOTE '"',
ESCAPE '\');
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.002 s, Affect 10 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 10
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT * FROM PUBLIC.TESTTAB ORDER BY A DESC LIMIT 10;
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.002 s, Affect 10 Rows.(SELECT,SHOW)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 10
ColNums : 9
AffectRows : 10
ID ColName ColType ColTypeSize ColMod TabOid
0 a 23 4 -1 16414
1 b 701 8 -1 16414
2 c 1043 -1 104 16414
3 d 25 -1 -1 16414
4 e 17 -1 -1 16414
5 f 17 -1 -1 16414
6 g 1082 4 -1 16414
7 h 1114 8 -1 16414
8 i 1700 -1 655366 16414
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgResDataPrint :
"2099372","9.1","0LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099371","9.1","9LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099370","9.1","8LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099369","9.1","7LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099368","9.1","6LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099367","9.1","5LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099366","9.1","4LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099365","9.1","3LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099364","9.1","2LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2099363","9.1","1LXG'ZXJ|"CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242",NULL,"2024-08-19 00:00:00","8.00"
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES(2.1,'LXG''ZXJ|CLX','HAHHAHAH','AAAAAA','BBBBBBBBBBBB','2024-08-19','2024-08-19',8);
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.001 s, Affect 1 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 1
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.002 s, Affect 10 Rows.(SELECT,SHOW)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 10
ColNums : 9
AffectRows : 10
ID ColName ColType ColTypeSize ColMod TabOid
0 a 23 4 -1 16414
1 b 701 8 -1 16414
2 c 1043 -1 104 16414
3 d 25 -1 -1 16414
4 e 17 -1 -1 16414
5 f 17 -1 -1 16414
6 g 1082 4 -1 16414
7 h 1114 8 -1 16414
8 i 1700 -1 655366 16414
ParamNums : 1
ParamType : [ 701 ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgResDataPrint :
"2097152","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097151","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097150","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097149","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097148","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097147","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097146","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097145","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097144","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097143","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.233 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgResDataPrint :
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES($1,$2,$3,$4,$5,$6,$7,$8),($9,$10,$11,$12,$13,$14,$15,$16);
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.001 s, Affect 2 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 2
ParamNums : 16
ParamType : [ 701,1043,25,17,17,1082,1114,1700,701,1043,25,17,17,1082,1114,1700 ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES($1,$2,$3,$4,$5,$6,$7,$8),($9,$10,$11,$12,$13,$14,$15,$16);
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSql : OK, Sql Elapsed Time 0.001 s, Affect 2 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : INSERT INTO PUBLIC.TESTTAB(b,c,d,e,f,g,h,i) VALUES(2.1,'LXG''ZXJ|CLX','HAHHAHAH','AAAAAA','BBBBBBBBBBBB','2024-08-19','2024-08-19',8);
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.001 s, Affect 1 Rows. (DML,DDL,COPY)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 1
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.001 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 9
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 a 23 4 -1 16414
1 b 701 8 -1 16414
2 c 1043 -1 104 16414
3 d 25 -1 -1 16414
4 e 17 -1 -1 16414
5 f 17 -1 -1 16414
6 g 1082 4 -1 16414
7 h 1114 8 -1 16414
8 i 1700 -1 655366 16414
ParamNums : 1
ParamType : [ 701 ]
2024-11-18 16:16:10-P[33855]-T[33855]-[Debug]-PgResDataPrintAsync:
"2097152","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097151","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097150","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097149","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097148","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097147","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097146","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097145","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097144","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
"2097143","1.1","LXG'ZXJ|CLX","HAHHAHAH","\x414141414141","\x424242424242424242424242","2024-08-19","2024-08-19 00:00:00","8.00"
RowNums : 10
2024-11-18 16:16:10-P[33855]-T[33855]-[Extra]-Sql Query : SELECT * FROM PUBLIC.TESTTAB WHERE B = $1 ORDER BY A DESC LIMIT 10;
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.214 s, Affect 0 Rows.(SELECT,SHOW,No Data)
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query :
COPY PUBLIC.TESTTAB(B,C,D,E,F,G,H,I)
FROM '/home/postgres/PgData.txt'
WITH(
FORMAT CSV,
DELIMITER '|',
NULL '',
QUOTE '"',
ESCAPE '\');
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.000 s, Affect 10 Rows. (DML,DDL,COPY)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 10
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query :
COPY PUBLIC.TESTTAB(B,C,D,E,F,G,H,I)
FROM STDIN
WITH(
FORMAT CSV,
DELIMITER '|',
NULL '',
QUOTE '"',
ESCAPE '\');
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.001 s, Affect 0 Rows.(SELECT,SHOW,COPY IN)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgCopyIn : OK, RowNums : 3.
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgCopyInEnd : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query : COMMIT;
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.001 s, Affect 0 Rows. (DML,DDL,COPY)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query :
SELECT
PkTab.TABLE_NAME,
STRING_AGG(PkTab.COLUMN_NAME,'|'),
STRING_AGG(ColTab.DATA_TYPE,'|'),
COUNT(PkTab.COLUMN_NAME)
FROM
(
SELECT
TABLE_CATALOG,
TABLE_SCHEMA ,
TABLE_NAME ,
COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
TABLE_CATALOG = $1
AND
TABLE_SCHEMA = $2
AND
POSITION_IN_UNIQUE_CONSTRAINT IS NULL
ORDER BY ORDINAL_POSITION
) PkTab
LEFT JOIN
(
SELECT
TABLE_CATALOG,
TABLE_SCHEMA ,
TABLE_NAME ,
COLUMN_NAME ,
DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_CATALOG = $3
AND
TABLE_SCHEMA = $4
) ColTab
ON
PkTab.TABLE_CATALOG = ColTab.TABLE_CATALOG
AND
PkTab.TABLE_SCHEMA = ColTab.TABLE_SCHEMA
AND
PkTab.TABLE_NAME = ColTab.TABLE_NAME
AND
PkTab.COLUMN_NAME = ColTab.COLUMN_NAME
GROUP BY
PkTab.TABLE_NAME;
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.021 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 4
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 table_name 19 64 -1 14040
1 string_agg 25 -1 -1 0
2 string_agg 25 -1 -1 0
3 count 20 8 -1 0
ParamNums : 4
ParamType : [ 19,19,19,19 ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgSchemaPkGet : OK, czg.public.
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgResDataPrintAsync:
"students","id|name","integer|character varying","2"
"testtab","a","integer","1"
RowNums : 2
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query :
SELECT
STRING_AGG(PkTab.COLUMN_NAME,'|'),
STRING_AGG(ColTab.DATA_TYPE,'|'),
COUNT(PkTab.COLUMN_NAME)
FROM
(
SELECT
TABLE_CATALOG,
TABLE_SCHEMA ,
TABLE_NAME ,
COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
TABLE_CATALOG = $1
AND
TABLE_SCHEMA = $2
AND
TABLE_NAME = $3
AND
POSITION_IN_UNIQUE_CONSTRAINT IS NULL
ORDER BY ORDINAL_POSITION
) PkTab
LEFT JOIN
(
SELECT
TABLE_CATALOG,
TABLE_SCHEMA ,
TABLE_NAME ,
COLUMN_NAME ,
DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_CATALOG = $4
AND
TABLE_SCHEMA = $5
AND
TABLE_NAME = $6
) ColTab
ON
PkTab.TABLE_CATALOG = ColTab.TABLE_CATALOG
AND
PkTab.TABLE_SCHEMA = ColTab.TABLE_SCHEMA
AND
PkTab.TABLE_NAME = ColTab.TABLE_NAME
AND
PkTab.COLUMN_NAME = ColTab.COLUMN_NAME
GROUP BY
PkTab.TABLE_NAME;
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.010 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 3
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 string_agg 25 -1 -1 0
1 string_agg 25 -1 -1 0
2 count 20 8 -1 0
ParamNums : 6
ParamType : [ 19,19,19,19,19,19 ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgTabPkGet : OK, czg.public.testtab
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgResDataPrintAsync:
"a","integer","1"
RowNums : 1
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query : SELECT MAX(a),MIN(a) FROM public.testtab
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.002 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 2
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 max 23 4 -1 0
1 min 23 4 -1 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgTabPkSplit : OK, Schema : public, Tab : testtab, Pk : a.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query : SELECT COUNT(*) FROM public.testtab
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 0.167 s, Affect 0 Rows.(SELECT,SHOW)
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 1
AffectRows : 0
ID ColName ColType ColTypeSize ColMod TabOid
0 count 20 8 -1 0
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:11-P[33855]-T[33855]-[Debug]-PgCntSingleTab : OK, Schema : public, Tab : testtab, RowNums : 2098355.
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-Sql Query :
COPY PUBLIC.TESTTAB(B,C,D,E,F,G,H,I)
TO '/home/postgres/PgDataOut.txt'
WITH(
FORMAT CSV,
DELIMITER '|',
NULL '',
QUOTE '"',
ESCAPE '\');
2024-11-18 16:16:11-P[33855]-T[33855]-[Extra]-PgMetaDataGet : OK.
2024-11-18 16:16:15-P[33855]-T[33855]-[Extra]-PgExecSqlAsync : OK, Elapsed Time 4.553 s, Affect 2098355 Rows. (DML,DDL,COPY)
2024-11-18 16:16:15-P[33855]-T[33855]-[Debug]-PgMetaDataPrint :
RowNums : 0
ColNums : 0
AffectRows : 2098355
ParamNums : 0
ParamType : [ ]
2024-11-18 16:16:15-P[33855]-T[33855]-[Debug]-PgDestroy : OK.