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を返します.
コマンド関数の実行結果は、PQresultStatusによって判断され、PQresultErrorMessageは、PQexecクエリに関連付けられたエラー情報を取得するために使用されます.
コマンドライン文字列commandには、セミコロンで区切られた複数の実行文を含めることもできます.PQexecで呼び出された複数のクエリーは、デフォルトでは1つのトランザクションで実行されます.たとえば、次の例では、私のcommand文に誤りがあると仮定すると、複数の文は実行されません.
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 }
-->
クエリ結果の情報セクションは簡単です.サンプルコードを見てください.
ここまで、ほとんどのEnterpriseDB(PostgreSQL Plus Advanced Server)データベースの日常開発作業をlibpqで完了することができます.
@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で完了することができます.