设为首页 收藏本站
查看: 1115|回复: 0

[经验分享] 发个C语言连接Postgresql程序(转)

[复制链接]

尚未签到

发表于 2016-11-21 10:36:46 | 显示全部楼层 |阅读模式
  一直用的是Oracle,今天要在postgresql写个程序,查了半天的pg官方文档件才搞定。
官方的例子有点简单,我把项目中的程序直接发过来供后来者学习和参考。
备注:
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>
static void sig_child(int signo);
static void task_fork();
static void run_task();
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();
    }  
   
}
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);
    }
}
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, 0, 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, 0, sizeof(conninfo));
        strcpy(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, 0, 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, 0, sizeof(sql_que));
            sprintf(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存在", PQgetvalue(res, i, 2));
                PQclear(res2);
            }
            else
            {
                PQclear(res2);
                memset(sql_que, 0, sizeof(sql_que));
                sprintf(sql_que, "insert into bank_pli_check (adm_no, adm_name, pli_no, pli_name) values ('%s', '%s', '%s', '%s')", PQgetvalue(res, i, 0), PQgetvalue(res, i, 1), PQgetvalue(res, i, 2), PQgetvalue(res, i, 3));
                res2 = PQexec(conn2, sql_que);//没有的记录将更新到表里面
                status = PQresultStatus(res2);
               
                if (status == PGRES_COMMAND_OK)
                {
                    LOGLINE; LOG("记录pli=[%s]已经更新到bank_pli_check表里", PQgetvalue(res, i, 2));
                }
                else
                {
                    LOGLINE; LOG("记录pli=[%s]插入bank_pli_check表失败", PQgetvalue(res, i, 2));
                }
                    
            }
            
        }
        
        res2 = PQexec(conn2, "END");
        PQclear(res);
        PQclear(res2);
        PQfinish(conn);
        PQfinish(conn2);
        sleep(60*60);
    }
   
    return;
}
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;
}
static int LOG_INIT(void)
{
    time_t timep;
    struct tm *time_ptr = NULL;
   
    time(&timep);
    time_ptr = localtime(&timep);
   
    memset(g_log_file, 0, 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, 0, sizeof(g_source_file));
    strcpy(g_source_file, __FILE__);
   
    return 0;
}
  http://bbs2.iyunv.com/thread-1497010-1-1.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-303360-1-1.html 上篇帖子: Postgresql: 动态SQL语句中不能使用Select into? 下篇帖子: postgreSQL在ubuntu环境下的安装使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表