libpq-PostgreSQLクライアントプログラミングインターフェース(二)----libpqのコマンド実行関数

12150 ワード

<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm; direction: ltr; color: #00000a; widows: 0; orphans: 0 }
P.western { font-family: "Liberation Serif", serif; font-size: 12pt; so-language: en-US }
P.cjk { font-family: "Droid Sans Fallback"; font-size: 12pt; so-language: zh-CN }
P.ctl { font-family: "DejaVu Sans"; font-size: 12pt; so-language: hi-IN }
TT.ctl { font-family: "DejaVu Sans Mono", monospace }
-->
libpqのコマンド実行関数は,PQexec,PQexecParams,PQprepare,PQpreparedである.
PQexecはサーバにコマンドを送信し、結果を待つ
定義:PGresult*PQexec(PGconn*conn,const char*command);
PQexecは、PGresultポインタまたはNULLを返します.
PGresult *res;
const char *command = "INSERT INTO mytable (username,weblog) VALUES ('ode','http://ode.cnblogs.com');";
res = PQexec(conn,command);

コマンド関数の実行結果は、PQresultStatusによって判断され、PQresultErrorMessageは、PQexecクエリに関連付けられたエラー情報を取得するために使用されます.
1 if(PQresultStatus(res) != PGRES_COMMAND_OK)
2 {
3         // throw exception or show error messages
4         cout << PQresultErrorMessage(res) << endl;
5 }
6 else
7 {
8         //do somthing...
9 }

コマンドライン文字列commandには、セミコロンで区切られた複数の実行文を含めることもできます.PQexecで呼び出された複数のクエリーは、デフォルトでは1つのトランザクションで実行されます.たとえば、次の例では、私のcommand文に誤りがあると仮定すると、複数の文は実行されません.
 
command = "INSERT INTO mytable (username,weblog) VALUES ('ode','http://ode.cnblogs.com');INSERT INTO mytable (username1,weblog) VALUES ('odevincent','http://odevincent.blog.51cto.com');";

 
2番目の文はエラーで、1番目の文も実行されません.PQresultmessageが返すエラーメッセージは次のとおりです.
エラー:関係「mytable」の「username 1」フィールドは存在しません
PostgreSQLの文書では、「クエリ文字列に明確なBEGIN/COMMITコマンドが存在しない限り、文字列全体を複数のトランザクションに分割します.このようにして返されるPGresult構造は、文字列で実行される最後のコマンドの結果のみを記述することに注意してください」と説明しています.複雑なビジネスの場合は、ストレージ・プロシージャまたは他の方法を使用することも考えられます.
<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm; direction: ltr; color: #00000a; widows: 0; orphans: 0 }
P.western { font-family: "Liberation Serif", serif; font-size: 12pt; so-language: en-US }
P.cjk { font-family: "Droid Sans Fallback"; font-size: 12pt; so-language: zh-CN }
P.ctl { font-family: "DejaVu Sans"; font-size: 12pt; so-language: hi-IN }
-->
クエリ結果の情報セクションは簡単です.サンプルコードを見てください.
        PGresult *res;
        const char* strSQL = "INSERT INTO mytable (cityname,zipcode) VALUES ('SHANGHAI','200200');INSERT INTO mytable (cityname1,zipcode) VALUES ('SHANGHAI','200202');";
        //res = PQexec(conn,"INSERT INTO mytable (cityname,zipcode) VALUES ('SHANGHAI','200200');");
        res = PQexec(conn,strSQL);
        if(PQresultStatus(res) != PGRES_COMMAND_OK)
        {
            cout << "command faild! PQresultStatus=" << PQresultStatus(res) << endl;
            // print error message
            cout << PQresultErrorMessage(res) << endl;
        }
        else
        {
            cout << "commit success.OID is : " << PQoidValue(res) << endl;
        }
        // important !!!
        PQclear(res);
        PGresult *res_getallrows;
        res_getallrows = PQexec(conn,"SELECT cityname,zipcode FROM mytable;");
        if(PQresultStatus(res_getallrows) != PGRES_TUPLES_OK)
        {
            cout << "QUERY faild! PQresultStatus=" << PQresultStatus(res_getallrows) << endl;
            // print error message
            cout << PQresultErrorMessage(res_getallrows) << endl;
        }
        else
        {
            // rows count
            cout << "PQntuples : " << PQntuples(res_getallrows) << endl;
            // fields count
            cout << "PQnfields : " << PQnfields(res_getallrows) << endl;
            int fieldsCount = PQnfields(res_getallrows) ;
            for(int fieldIndex = 0;fieldIndex < fieldsCount;++fieldIndex)
            {
                cout << "field " << fieldIndex << " name is : " << PQfname(res_getallrows,fieldIndex) << endl;
                // PQfformat
                cout << "field " << fieldIndex << " format is : " << PQfformat(res_getallrows,fieldIndex) << endl;
                // PQfmod
                cout << "field " << fieldIndex << " mod is : " << PQfmod(res_getallrows,fieldIndex) << endl;
                // PQfsize
                cout << "field " << fieldIndex << " size is (varchar will return -1.): " << PQfsize(res_getallrows,fieldIndex) << endl;
            }
            cout << "cityname fnumber : " << PQfnumber(res_getallrows,"cityname") << endl;
            cout << "zipcode fnumber : "  << PQfnumber(res_getallrows,"zipcode") << endl;
            /*
             *char *PQgetvalue(const PGresult *res,
             int row_number,
             int column_number);
            */
            int row_number = 0,column_number = 0;
            if(!PQgetisnull(res_getallrows,row_number,column_number) )
            {
                cout << "row" << row_number << ",column" << column_number << " value is : " << PQgetvalue(res_getallrows,row_number,column_number) << endl;
            }
        }
        // important !!!
        PQclear(res_getallrows);

ここまで、ほとんどのEnterpriseDB(PostgreSQL Plus Advanced Server)データベースの日常開発作業をlibpqで完了することができます.