postgresql獲取表最后更新時間(通過發布訂閱機制將消息發送給應用程序)


一、創建測試表

CREATE TABLE weather(
city varchar(80),
temp_lo int,  --最低溫度
temp_hi int,  --最高溫度
prcp real,     --濕度
date date
);

二、創建觸發器函數

create or replace function table_update_notify() returns trigger as $$
begin 
    perform pg_notify('table_update',json_build_object('table',TG_TABLE_NAME,'timestamp',current_timestamp)::text);
    return new;
end;
$$ language plpgsql;

三、創建觸發器

drop trigger if exists n_weather_u on weather;
create trigger n_weather_u after insert or update or delete on weather
for each statement execute procedure table_update_notify();

四、應用程序代碼

代碼有重連機制,數據庫服務器停止或者網絡斷開應用程序不退出,數據庫服務起來或者網絡恢復后應用程序會自動重連並重新訂閱消息

#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>

static void exit_nicely(PGconn *conn)
{       
        PQfinish(conn);
        exit(1);
}

int main(int argc,char **argv)
{
        const char *conninfo;
        PGconn *conn;
        PGresult *res;
        PGnotify *notify;

        conninfo = "hostaddr=192.168.147.1 port=5432  dbname=postgres user=postgres password=123456";
        conn = PQconnectdb(conninfo);
        if(PQstatus(conn) != CONNECTION_OK)
        {       
                fprintf(stderr,"connection to database failed:%s",PQerrorMessage(conn));
                exit_nicely(conn);
        }

        res = PQexec(conn,"listen table_update");
        if(PQresultStatus(res) != PGRES_COMMAND_OK)
        {
                fprintf(stderr,"listen command failed:%s",PQerrorMessage(conn));
                PQclear(res);
                exit_nicely(conn);
        }
        
        PQclear(res);

        while(1)
        {
                //執行select 1命令來判斷數據庫連接是否正常,不正常則自動重連,並重新訂閱通知
                PGresult *res_getallrows;
                res_getallrows = PQexec(conn,"select 1;");
            //    printf("PQresultStatus(res_getallrows)=%d\n",PQresultStatus(res_getallrows));
                if(PQresultStatus(res_getallrows) != PGRES_TUPLES_OK)
                {
                    conn = PQconnectdb(conninfo);
                    if(PQstatus(conn) != CONNECTION_OK)
                    {       
                        usleep(1000);
                        continue;
                    }
                    else
                    {
                        res = PQexec(conn,"listen table_update");
                        if(PQresultStatus(res) != PGRES_COMMAND_OK)
                        {
                            PQclear(res);
                            usleep(1000);
                            continue;
                        }
                    }
                }
            
                PQconsumeInput(conn);
                while((notify = PQnotifies(conn)) != NULL)
                {
                        fprintf(stderr,"async notify of '%s' received from backend PID %d,extra:%s\n",notify->relname,notify->be_pid,notify->extra);
                        PQfreemem(notify);
                }
                
                usleep(1000);
        }

        fprintf(stderr,"Done.\n");
        PQfinish(conn);
        return 0;
}

編譯:gcc -I/opt/pgsql/include -L/opt/pgsql/lib -o test testpq.c -lpq

五、測試

服務器端執行sql

insert into weather values('nanjing',20,40,0.25,'2018-06-29');
update weather set temp_lo = 18 where city = 'nanjing';
delete from weather where city = 'nanjing'

應用程序獲取表變化時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM