一、創建測試表
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'
應用程序獲取表變化時間