postgresql從入門到菜鳥(六)libpq連線postgres資料庫
上一期講了一些如何通過jdbc連線postgresql資料庫,這一期準備說一說如何通過libpq連線postgresql資料庫。
上一期的jdbc是postgresql的java語言應用程式介面,這一期的libpq對應的是postgresql的C語言應用程式介面。
這裡依舊分為三個模組來講:
一.獲取連線
二.執行select語句
三.執行insert,delete,update語句
第一部分:獲取連線
要使用libpq連線postgresql資料庫首先要引用libpq的標頭檔案libpq-fe.h
然後建立連線字串和PGconn結構體,設定連線字串後就可以通過連線字串獲取連線了
const char *conninfo;
PGconn *conn;
conninfo = "host=127.0.0.1 port=5433 dbname=smoondb user=postgres";
conn = PQconnectdb(conninfo);
注意如果這裡預設連線關鍵字的話,libpq將使用預設關鍵字的預設值進行連線,連線關鍵字的預設值可以參考官方手冊。
在jdbc中,我們可以通過try catch的方式進行連線錯誤捕獲,在libpq中也提供了判斷連線是否成功建立的介面:
if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); exit_nicely(conn);//關閉連線並執行清理操作 }
這裡如果連線不成功的話會返回服務端返回的錯誤message,如果成功的話後面就可以通過conn操作資料庫了。
第二部分:執行select語句
在獲取到PGconn例項後,我們就可利用PGconn例項進行對資料庫的操作了,和jdbc不同,jdbc中查詢語句和更新語句會分別呼叫executeQuery()和executeUpdate(),而libpq中使用的是同一個介面。
Lipq執行sql命令的核心函式為PQexec(PGconn *conn, const char *command);其中第一個引數為連線。第二個為執行的命令,其中command字串可以包含多條執行命令,需要注意的是如果不加入begin或者commit的關鍵字,command字串中的所有命令將在一個事務中執行,並且只要其中一條失敗,就會導致整個command執行失敗。
PQexec函式的返回型別為PGresult,如果返回值為null,說明執行失敗,可以通過PQerrorMessage()方法檢視錯誤訊息。
在libpg中,查詢語句和更新語句都是通過PQexec函式執行,但是很明顯對於這兩種語句我們需要的返回值肯定不同,所以在解析PGresult時,libpq提供了不同的解析函式,這部分先說說解析查詢結果用到的幾個函式
PQnfields(PGresult *res):用於獲取結果集中列的數目
PQfname(PGresult *res,int i):用於獲取結果集中列的名稱
PQntuples(PGresult *res):用於獲取結果集中行的數目
PQgetvalue(PGresult *res,int i,int j):用於獲取結果集中i行j列的值
比如下面這一段:
res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");//為查詢語句宣告一個遊標
if (PQresultStatus(res) != PGRES_COMMAND_OK)//判斷遊標生成是否成功
{
fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
//這裡需要注意不再使用的PGresult需要及時釋放,否則可能會造成記憶體洩漏
PQclear(res);
res = PQexec(conn, "FETCH ALL in myportal");//FETCH ALL表示從結果中取回全部資料
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
// 首先,打印出列名
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
// 接下來,打印出行
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));//列印值
printf("\n");
}
PQclear(res);
第三部分:執行insert,delete,update語句
對於select語句,我們在解析PGresult時需要的是結果集,所以在上面呼叫了以上幾個函式,但是修改語句我們更關心的受影響的行數,所以對於修改語句可以通過PQntuples(const PGresult *res)獲取受影響函式,其中對於PGresult而言它的成員中包含了所有執行的結果,不同的解析函式只是用來取得PGresult中相應的成員而已,有興趣的同學可以去看一看PGresult結構體的實現,裡面對於所有的成員都有比較清楚的描述。
下面貼一段執行插入語句的例子:
res = PQexec(conn, "delete from student where sid=4;");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "delete failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
printf("updatelin:%s",PQcmdTuples(res));//解析並列印受影響行數
PQclear(res);
完整的例子程式可以在官方手冊中找到這裡就不再貼出了。
最後說說libpq程式的編譯,對於寫好的.c檔案,可以執行以下命令生成可執行檔案
gcc -L $libpath -I $includepath -lpq -o testlipq testlipq.c