天天看點

任意語言通路PostgreSQL:C語言接口

作為一名系統管理者,可能每天都要通過某段程式連接配接到資料庫。開源軟體的一個好處是可以根據需要修改程式代碼。如果程式背景使用PostgreSQL資料庫,可以很容易用各種語言對其進行通路。本文作為系列文章的第一篇,會陸續介紹C、C++、PHP、Tcl、Python及Perl等程式設計語言對PostgreSQL的通路方法。

  需要說明的是,本文不太适合完全沒有程式設計經驗的讀者。不過隻要讀者有基本的SQL知識,以及懂得至少一種程式設計語言即可看懂。也許讀者正在使用的系統是Linux,但是隻要使用的用戶端API接口在其他系統可用,則程式代碼不需更改即可在其他作業系統上正常使用。本文所示的代碼全部基于Postgre 9.1,是目前最新的穩定版本,已經安裝并經過測試。在本文的操作環境中,用戶端與服務端位于不同的計算機,但位于同一區域網路内,這種情況下可以在用戶端通過指令gpsql -U postgre -h x.x.x.x很容易地連接配接到服務端。

  首先要確定在用戶端機器上有安裝軟體的權限,并且最好確定目前使用的資料庫隻做目前測試用,以免任何因不小心的操作導緻重要資料的損壞。

  C語言接口

  在與資料庫連接配接方面,C語言是一種常用語言,許多資料庫都是用C寫的。該語言高效靈活,是以如果想要寫一款用戶端接口,不管是僅僅包含控制台還是基于GUI的,并且不想用到浏覽器,C語言也許是最好的選擇。

  連接配接C語言與Postgres使用的庫名為libpq,它與PostgreSQL源碼樹綁定在一起。如果安裝資料庫系統時使用的是二進制檔案而不是從源碼編譯安裝,libpq可被單獨安裝,但也要記得需要使用選項-dev package(或-devel,取決于Linux系統的版本)。在Debian及其分發版上,安裝libpq的指令為 #aptitude install libpq-dev。在基于RedHat的系統上,如CentOS,可以在postgresqlxx-libs包中找到libpq,其中xx為主要和次要版本号。是以要連接配接到PostgreSQL 9.1資料庫,如果使用Fedora16,則需要安裝postgresql91-lib或postgresql-devel。由于RHEL/CentOS使用者大多使用Postgres庫,導緻程式的名稱可能會有一些不同,而且由于Fedora使用者能夠使用更多最新的包,是以僅僅在使用一個舊版本時才需要第三方庫。簡而言之,任何支援PostgreSQL的系統均有其可用的libpq。

  除了C語言,libpq同時也是C++、Perl和Tcl的API引擎,提供基本的函數對資料庫進行連接配接、查詢和修改。許多常用的函數都包含“PQ”字首,如PQconnectdb或PQerrormessage。更多示例可檢視PostgreSQL文檔或檢視src/test/examples。在C程式檔案中,包含libpq-fe.h頭檔案并在編譯時添加相應的連結标記-lpq。

  安裝并設定好之後,要做的第一件事就是連接配接資料庫。PQconnectdb()函數帶一個char *conninfo格式的參數,參數格式如dbname=[database_name],當然也可以是其他内容,隻要格式對即可,最常用的關鍵字為host,hostaddr(numeric格式,以避免無用的DNS查詢),port,user,password與sslmode。如果不使用參數,則會使用預設選項。假設伺服器位址為192.168.0.101,username為postgres,資料庫名為testdb1,嘗試連接配接資料庫的代碼如下所示:

#include <stdio.h>

#include <libpq-fe.h>

int main(int argc,char argv[])

{

    const char *conninfo;

    PGconn *conn;

    if (argc > 1)

        conninfo = argc[1];

    else

    {

        printf("Not enough arguments, exiting...");

        return 1;

    }

    conn = PQconnectdb(conninfo);

    /*Check to see how I did */

    if(PQstatus(conn) = CONNECTION_OK)

        printf("Connection succeeded.\n");

        /*Do something to deal with the error*/

}

将代碼儲存為testlibpq并編譯,編譯後的程式用法如下:

$ testlibpg "hostaddr=192.168.0.101 user=postgres dbname=testdb1"

如果不出錯誤,會在螢幕上看到提示“Connection succeeded.”,表示連接配接資料庫成功,不過上文并沒有什麼實際用處。那麼何為實際用處呢----對資料進行查詢,但這裡先介紹如何斷開連接配接,即調用PQfinish,該函數隻有一個參數PGconn *conn,并傳回void。

  PQexec函數執行查詢,參數為PGconn *conn與const char *command,傳回一個PGresult類型的對象。在如下示例中,聲明一個PGresult變量,并向伺服器發送一個指令。讀者可自行編寫檢查連接配接與否以及錯誤處理的代碼。

  PGresult *res;

  res = PQexec(conn, "SELECT * FROM mydatabase");

  PQclear(res);

顯然這段代碼無法編譯,隻是為了向讀者展示libpq庫提供的功能,而不是直接提供可用代碼。不過在這段代碼中,res包含了查詢結果,讀者可以任意對其進行解析。PQresultStatus可以查詢指令的狀态,該函數傳回PGRES_COMMAND_OK或 PGRES_FATAL_ERROR.。可在PostgreSQL項目頁面找到exec函數的一個綜合清單。

  下面介紹一些有用的函數,例如,PQntuples函數将給定的res作為參數,以整數類型傳回表中列的數量。如果查詢的狀态為PGRES_TUPLES_OK,則它以PGresult對象為參數,并傳回一個整型值。PQnfields函數給出每行的列數。PQfname函數傳回與某數字關聯的列的名字,PQfnumber函數功能則完全相反。要得到某一單元的值,需要将PGresult以及單元的列号和行号傳給PQgetvalue函數。

  可以看到這些函數都比較簡單,但PQexec不能同時處理多個SQL指令,因為該函數隻能傳回一個結構,如果有多個指令,則隻能傳回最後一個指令的結果。另一個不足是,PQexec在執行一個指令時會一直等到指令傳回,是以讀者在使用該指令遇到阻塞執行時要分外小心。如果這些不足影響到讀者使用者的使用,可以使用其它函數代替,如PQsendQuery和PQgetResult等,可使用這些函數來進行異步查詢處理。

本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/792475,如需轉載請自行聯系原作者