一直用的是Oracle,今天要在postgresql写个程序,查了半天的pg官方文档件才搞定。@H_502_1@
官方的例子有点简单,我把项目中的程序直接发过来供后来者学习和参考。@H_502_1@
备注:
1,这个程序功能是使2台服务器的postgresql数据库中的一个表保持一致。
2,加了进程重启功能。
3,postgresql有自动提交回滚功能,害的我在官方api文档找了半天的事务回滚在哪里(高手莫笑,哈哈)
4,程序最好总是在BEGIN和END之间 *** 作数据库,哪怕仅仅是select *** 作。
5,若遇乱码问题,请在SQL语句前加set clIEnt_enCoding = 'GBK';
/*
*Program name : updateplicheck.c
*Author : liu lin
*Date : 20090701
*/
#include "public.h"
#include "db_manager.h"
#include "libpq-fe.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>@H_502_1@
static voID sig_child(int signo);
static voID task_fork();
static voID run_task();@H_502_1@
int main(voID)
{
int pID; //创建守护进程开始
if ((pID = fork()) < 0)
{
LOGliNE; LOG("创建进程 *** 作失败");
exit(1);
}
if (pID > 0)
exit(0);
setsID();
signal(SIGHUP,SIG_IGN);
umask(0); //创建守护进程结束
signal(SIGCHLD,sig_child);
task_fork();
while (1)
{
pause();
}
}@H_502_1@
static voID task_fork()
{
pID_t pID;
if ((pID = fork()) < 0)
{
LOGliNE,LOG("创建子进程失败");
exit(1);
}
if (pID == 0)
{
signal(SIGCHLD,SIG_DFL);
run_task();
exit(0);
}
}@H_502_1@
static voID run_task(voID)
{
char conninfo[256] = {0};
PGconn *conn; //连接代理服务器数据库
PGresult *res;
PGconn *conn2; //连接本地服务器数据库
PGresult *res2;
int status;
char sql_que[1024] = {0};
int i;
int update_times = 0;
while (update_times < 12*7)//每个进程只负责一周的更新,防止内存泄露
{
update_times++;
memset(conninfo,sizeof(conninfo));
strcpy(conninfo,"host=192.168.1.110 dbname=ydds user=postgres password=postgres port=5432 connect_timeout=30");
conn = PQconnectdb(conninfo);
if(PQstatus(conn) != CONNECTION_OK)
{
LOGliNE; LOG("与更新源postgresql数据库连接失败,时间是[%s]",TIME());
PQfinish(conn);
sleep(60*60);
continue;
}
else
{
LOGliNE; LOG("与更新源postgresql数据库连接成功,时间是[%s]",TIME());
}
memset(conninfo,"host=localhost dbname=ydds user=postgres password=postgres port=5432 connect_timeout=30");
conn2 = PQconnectdb(conninfo);
if(PQstatus(conn2) != CONNECTION_OK)
{
LOGliNE; LOG("与本地postgresql数据库连接失败,时间是[%s]",TIME());
PQfinish(conn);
PQfinish(conn2);
sleep(60*60);
continue;
}
else
{
LOGliNE; LOG("与本地postgresql数据库连接成功,时间是[%s]",TIME());
}
res2 = PQexec(conn2,"BEGIN");
if(PQresultStatus(res2) != PGRES_COMMAND_OK) //成功完成一个不返回数据的命令
{
LOGliNE; LOG("执行BEGIN失败[%s]",PQerrorMessage(conn));
PQclear(res2);
PQfinish(conn);
PQfinish(conn2);
sleep(60*60);
continue;
}
PQclear(res2);
memset(sql_que,sizeof(sql_que));
sprintf(sql_que,"select adm_no,adm_name,pli_no,pli_name from bank_pli_check");
res = PQexec(conn,sql_que);
status = PQresultStatus(res);
if (status != PGRES_TUPLES_OK) //成功执行一个返回数据的查询查询
{
LOGliNE; LOG("查询表bank_pli_check失败");
PQclear(res);
PQfinish(conn);
PQfinish(conn2);
sleep(60*60);
continue;
}
for (i = 0; i < PQntuples(res); i++)
{
memset(sql_que,"select pli_no from bank_pli_check where pli_no = '%s'",PQgetvalue(res,i,2));
res2 = PQexec(conn2,sql_que);//查看该条记录是否已经存在
status = PQresultStatus(res2);
if (status != PGRES_TUPLES_OK)//注意一个碰巧检索了零条元组的SELECT仍然显示PGRES_TUPLES_OK
{
LOGliNE; LOG("查询表bank_pli_check失败");
PQclear(res);
PQclear(res2);
PQfinish(conn);
PQfinish(conn2);
sleep(60*60);
continue;
}
if (PQntuples(res2) != 0)
{
LOGliNE; LOG("记录pli=[%s]已经在bank_pli_check存在",2));
PQclear(res2);
}
else
{
PQclear(res2);
memset(sql_que,"insert into bank_pli_check (adm_no,pli_name) values ('%s','%s','%s')",0),1),2),3));
res2 = PQexec(conn2,sql_que);//没有的记录将更新到表里面
status = PQresultStatus(res2);
if (status == PGRES_COMMAND_OK)
{
LOGliNE; LOG("记录pli=[%s]已经更新到bank_pli_check表里",2));
}
else
{
LOGliNE; LOG("记录pli=[%s]插入bank_pli_check表失败",2));
}
}
}
res2 = PQexec(conn2,"END");
PQclear(res);
PQclear(res2);
PQfinish(conn);
PQfinish(conn2);
sleep(60*60);
}
return;
}@H_502_1@
static voID sig_child(int signo)
{
pID_t pID;
int status;
while ((pID = waitpID(-1,&status,WNOHANG)) > 0)
{
LOGliNE; LOG("子进程[%d]]退出, 时间是[%s]",pID,TIME());
task_fork();
}
return;
}@H_502_1@
static int LOG_INIT(voID){ time_t timep; struct tm *time_ptr = NulL; time(&timep); time_ptr = localtime(&timep); memset(g_log_file,sizeof(g_log_file)); sprintf(g_log_file,"%s%s.log.%d%02d%02d",LOG_PATH,__file__,(1900 + time_ptr->tm_year),(1 + time_ptr->tm_mon),(time_ptr->tm_mday)); memset(g_source_file,sizeof(g_source_file)); strcpy(g_source_file,__file__); return 0;}@H_502_1@ 总结
以上是内存溢出为你收集整理的一个用C语言连接PostgreSQL的测试代码全部内容,希望文章能够帮你解决一个用C语言连接PostgreSQL的测试代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)