예제
번역 : 정재익
원본출처 : http://www.ca.postgresql.org/docs/momjian/writing_apps/node3.html
예제로서 다음 C 응용프로그램을 살펴보자:
/*
* libpq sample program
*/
#include
#include
#include "libpq-fe.h" /* libpq header file */
int
main()
{
char state_code[3]; /* holds user state code */
char query_string[256]; /* holds constructed SQL query */
PGconn *conn; /* holds database connection */
PGresult *res; /* holds query result */
int i;
[color=#FF0000]conn = PQconnectdb("dbname=test");[/color] /* connect to the database */
if (PQstatus([color=#FF0000]conn[/color]) == CONNECTION_BAD) /* did the connection fail? */
{
fprintf(stderr, "Connection to database failed.\n");
fprintf(stderr, "%s", PQerrorMessage(conn));
exit(1);
}
printf("Enter a state code: "); /* prompt user for a state code */
scanf("%2s", state_code);
sprintf(query_string, /* create an SQL query string */
"SELECT name \
FROM statename \
WHERE code = '%s'", state_code);
[color=#0000FF]res = PQexec([/color][color=#FF0000]conn[/color][color=#0000FF], query_string);[/color] /* send the query */
if (PQresultStatus(res) != PGRES_TUPLES_OK) /* did the query fail? */
{
fprintf(stderr, "SELECT query failed.\n");
PQclear(res);
PQfinish(conn);
exit(1);
}
for (i = 0; i < [color=#00FF00]PQntuples([/color][color=#0000FF]res[/color][color=#00FF00])[/color]; i++) /* loop through all rows returned */
printf("%s\n", [color=#00FF00]PQgetvalue([/color][color=#0000FF]res[/color][color=#00FF00], i, 0)[/color]); /* print the value returned */
[color=#0000FF]PQclear(res);[/color] /* free result */
[color=#FF0000]PQfinish(conn);[/color] /* disconnect from the database */
return 0;
이 예제는 PostgreSQL: Introduction and Concepts 라는 책의 Interfaces 라는 chapter에
실려 있는 예제이다. 만약 이 예제와 친숙치 않다면 http://www.postgresql.org/docs/awbook.html
에서 좀더 상세하게 이 응용프로그램을 리뷰해 보시기 바란다.
위의 프로그램에서 데이터베이스에 대한 접속/접속해제 는 빨간색으로
표시된 행에서 실행되고, 질의를 주고 그 결과를 지우는 작업은 파란색 행에서
실행된다. 그리고 결과조회는 녹색 행으로 표시되어 있다.
conn 구조체는 데이터베이스 접속에 대한 정보를 저장하고 있으며, res 는 결과로
돌아온 정보를 저장하고 있다. 색깔로서 구분해 놓은 것과 마찬가지로 conn 은 res 를
얻기 위해서 사용되었으며, res 는 결과를 조회하기 위해 사용되어지고 있다. 다음 TCL
프로그램에서도 같은 방식으로 동작하고 있음을 알수 있다. 여기서도 conn 과 res 를 동일한
목적으로 이용하고 있음을 알수 있다.
#!/usr/local/pgsql/bin/pgtclsh
#
# pgtclsh sample program
#
[color=#FF0000]set conn [pg_connect -conninfo "dbname=test"][/color] ;# connect to the database
puts -nonewline "Enter a state code: " ;# prompt user for a state code
flush stdout
gets stdin state_code
;# send the query
[color=#0000FF]set res [pg_exec [/color][color=#FF0000]$conn[/color][color=#0000FF] \
"SELECT name \
FROM statename \
WHERE code = '$state_code'"] [/color]
[color=#00FF00]set ntups [pg_result [/color][color=#0000FF]$res[/color][color=#00FF00] -numTuples][/color]
for {set i 0} {$i < $ntups} {incr i} { ;# loop through all rows returned
puts stdout [lindex [[color=#00FF00]pg_result [/color][color=#0000FF]$res[/color][color=#00FF00] -getTuple $i] 0][/color] ;# print the value returned
}
pg_disconnect $conn ;# disconnect from the database
좀더 편리하게 설졍하여 사용이 가능하다. 예를 들면 여러개의 접속 요청을 하여 여러개의 접속
핸들을 생성할수 있다. 심지어 서로 다른 사용자로서 서로 다른 데이터베이스로 접근할수도 있다.
만약 프로그램 실행 도중 나중에라도 사용할 필요가 있다면 결과 핸들을 지우는 작업은 생략할수도
있다. 물론 result 는 static 으로 정의되어 있다. result 는 질의가 실행될 당시에 얻어 진다. Libpq 는
비동기적으로 동시에 여러개의 질의를 보내고 그 결과를 받을수 있도록 되어 있다.
Examples
As an example, look at the following C application:
/*
* libpq sample program
*/
#include
#include
#include "libpq-fe.h" /* libpq header file */
int
main()
{
char state_code[3]; /* holds user state code */
char query_string[256]; /* holds constructed SQL query */
PGconn *conn; /* holds database connection */
PGresult *res; /* holds query result */
int i;
conn = PQconnectdb("dbname=test"); /* connect to the database */
if (PQstatus(conn) == CONNECTION_BAD) /* did the connection fail? */
{
fprintf(stderr, "Connection to database failed.\n");
fprintf(stderr, "%s", PQerrorMessage(conn));
exit(1);
}
printf("Enter a state code: "); /* prompt user for a state code */
scanf("%2s", state_code);
sprintf(query_string, /* create an SQL query string */
"SELECT name \
FROM statename \
WHERE code = '%s'", state_code);
res = PQexec(conn, query_string); /* send the query */
if (PQresultStatus(res) != PGRES_TUPLES_OK) /* did the query fail? */
{
fprintf(stderr, "SELECT query failed.\n");
PQclear(res);
PQfinish(conn);
exit(1);
}
for (i = 0; i < PQntuples(res); i++) /* loop through all rows returned */
printf("%s\n", PQgetvalue(res, i, 0)); /* print the value returned */
PQclear(res); /* free result */
PQfinish(conn); /* disconnect from the database */
return 0;
}
This example is described in the Interfaces chapter of my book, PostgreSQL: Introduction and Concepts.
Please review the application details at http://www.postgresql.org/docs/awbook.html if you are unfamiliar with it.
In the above program, connection/disconnection to the database is processed by the lines
in red, a query is issued and the result cleared in blue, and the result is accessed in green.
The conn structure holds connection information, and res holds result information. As you
can see from the colors, conn is used to obtain res, and res is used to access results. You
can see the following TCL program follows the same pattern. It even uses conn and res in the same way:
#!/usr/local/pgsql/bin/pgtclsh
#
# pgtclsh sample program
#
set conn [pg_connect -conninfo "dbname=test"] ;# connect to the database
puts -nonewline "Enter a state code: " ;# prompt user for a state code
flush stdout
gets stdin state_code
;# send the query
set res [pg_exec $conn \
"SELECT name \
FROM statename \
WHERE code = '$state_code'"]
set ntups [pg_result $res -numTuples]
for {set i 0} {$i < $ntups} {incr i} { ;# loop through all rows returned
puts stdout [lindex [pg_result $res -getTuple $i] 0] ;# print the value returned
}
pg_disconnect $conn ;# disconnect from the database
Fancier configurations are possible. For example, you can create multiple connection handles
by issuing multiple connection requests, even to different databases or as different users.
You can also skip clearing results and use them later in your application. Of course,
results are static. They represent the result at the time the query was executed. LIbpq even
has an asynchronous set of library calls that allow multiple queries to be sent and retrieved simultaneously.
|