C言語で Postgres にアクセスする方法

RedHut6.2J Linux
C言語で Postgres にアクセスする方法について

(注意)コンパイルする場合、ライブラリが必要な場合、コンパイル時のオプションの書き方は、
libhoge をリンクする場合は  -lhoge となる。

例 gcc libpq1.c -o gserv -I/usr/local/pgsql/include -L/usr/local/pgsql/lib -lpq

例の解説 -I インクルードファイルのディレクトリ。
      -L ライブラリファイルのディレクトリ。
       -ipq C言語-Postgresインターフェースライブラリ libpq をリンクせよ。


-o オプション  作成する実行ファイル名を指定する
-o gserv 作成する実行ファイル名は、gserv

-------------------------------------------------------------------------------------

データベースにアクセスする

1 サーバを起動する pg_ctl -w start 停止は pg_ctl -w stop
  C言語にてアクセスする場合はサーバが動いていないと出来ないので注意。

2 データベースに接続する。ユーザはどのデータベースにも出接続できる。

psql hogedb //現在のユーザがhogedb というデータベースに接続する
psql -U taro hogedb // taro というユーザ名でhogedb に接続する
psql -U taro // taro というユーザ名でデフォルトの taro というデータベースに接続
psql -u hogedb // hogedb に接続する。ユーザ名が質問される

3 切断は \q

4 テーブルの作成例

base0 というテーブルの要素を名前、年齢、住所、国籍とすると、それを作るSQL文は

create table base0 (name text, age int, add text, nation int); となる。

  要素が文字列の場合は text として、数値の場合は int として定義する。
  国籍が、int 型になっているのは、 別に国籍コードとして数値で管理するから。

  CREATEというメッセージがでたら、作成完了だ。
  select * from base0 で、テーブルを確かめると、

name | age | add | nation
------+-----+-----+---
(0 rows)

  と、表示される。

  存在するテーブルの削除は、drop table (テーブル名) 例 drop table test0;
  最後のセミコロンを忘れずに。

4−A フィールドの追加

  作成したテーブルに後からフィールドを追加する。

例 テーブル t2 に新しいフィールド password を追加する。

   alter table t2 add column password text;

4−A フィールドの削除

   alter table t2 drop column password;

5 データを追加する。

  追加のほうほうは、  insert into (テーブル名) values(フィールドの値); となる。

  例 insert into base0 values ( '山田太郎', 25, '練馬区土支田', 8);

  実行すると、 insert 18726 1 というようなメッセージが表示される。
  その後に select * from base0; とやれば登録したデータが表示される。

6 インデックスの作成

  テーブルにインデックスを作成する。インデックスを作成すると、レコードにユニークなインデックスが追加される?。

create index testindex on t2(name);

7 データの取り出し

  データを取り出すためには select 文を使用する。select (フィールド) from (テーブル) where (条件)

テーブルt2 から
全てのフィールド
を取り出す場合

select * from t2;
結果
select * from t2;
     name   |   point | age | sex
----------------+-------+-----+-----
ひし形の理恵子 | 5 | 25 | 1
axsdfvvvv | 5 | 25 | 1
datat0 | 8 | 6 | 2
(3 rows)
テーブル t2 から
name が山田
の全フィールドを取り出す。
select * from t2 where name='山田';
結果
meg=# select * from t2 where name='山田';
name | point | age | sex
------+-------+-----+-----
(0 rows)
テーブル t2 から
age が10以上の
name フィールド
を取り出す

select name from t2 where age>10;
結果
meg=# select name from t2 where age>10;
name
----------------
ひし形の理恵子
axsdfvvvv
(2 rows)
テーブル t2 から
age が10以上で
sex フィールドが 1の
全てのフィールドを取り出す

select * from t2 whare age>10 And sex=1;
結果
meg=# select * from t2 where age>10 Or sex=1;
name | point | age | sex
----------------+-------+-----+-----
ひし形の理恵子 | 5 | 25 | 1
axsdfvvvv | 5 | 25 | 1
(2 rows)

テーブル1の項目1の値を”A”に、項目2の値を1に更新する。ただし、項目A=0のデータのみ
Update テーブル1 Set 項目1 = "A", 項目2 = 1 Where 項目A = 0

データの一部を書き換える場合

update t2 set point='0'; テーブルt2の point 全てに0をセットする

PSQL用のコマンド一覧 \ は、LINUXでは逆スラッシュ \
\? コマンド一覧を表示
\h command コマンドのヘルプを表示
\d table テーブルの定義内容を表示
\df 関数の一覧表を表示
\dT 型の一覧表を表示
\do オペレータの一覧表を表示
\dS システムテーブルの一覧表を表示
\dt ユーザテーブルの一覧表を表示
\l データベースの一覧表を表示
\! shell-command シェルコマンドの実行

C言語インターフェース(LIBPQ)にて稼動中のPostgresデータベースにアクセスするためのコード


/*
* testlibpq.c
* POSTGRES のフロントエンド・ライブラリ LIBPQ の C バージョンのテスト
*
*
*/
#include <stdio.h>
#include "libpq-fe.h"
 
void
exit_nicely(PGconn* conn)
{
 PQfinish(conn);
 exit(1);
}
 
main()
{
char *pghost, *pgport, *pgoptions, *pgtty;
char* dbName;
int nFields;
int i,j;
 
/* FILE *debug; */
 
PGconn* conn;
PGresult* res;
 
/* もしパラメータがヌルの場合は,バックエンド接続のためにパラメータを
セットすることからはじめる,そして,システムは理にかなったデフォルトを
環境変数から捜し,失敗するとハードコーディングされた定数を使う. */
 
pghost = NULL; /* バックエンド・サーバのホスト名 */
pgport = NULL; /* バックエンド・サーバのポート */
pgoptions = NULL; /* バックエンド・サーバを起動するときの特別なオプション */
pgtty = NULL; /* バックエンド・サーバのデバッグをする端末 */
dbName = "template1"; // 接続するデータベースの名前
 
/* データベースに接続をはる */
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);

/* バックエンド接続が確立したことを確認する */
if (PQstatus(conn) == CONNECTION_BAD) {
 fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
 fprintf(stderr,"%s",PQerrorMessage(conn)); exit_nicely(conn);
}
 
/* debug = fopen("/tmp/trace.out","w"); */
/* PQtrace(conn, debug); */
 
/* トランザクション・ブロックの開始 */
res = PQexec(conn,"BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 fprintf(stderr,"BEGIN command failed\n");
 PQclear(res);
 exit_nicely(conn);
}
 
/* メモリー・リークを避ける為に不要となったら PGresult を PQclean すべき */
PQclear(res);
 
/* データベースのシステム・カタログ pg_database からインスタンスを
フェッチする */
res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 fprintf(stderr,"DECLARE CURSOR command failed\n");
 PQclear(res); exit_nicely(conn);
}
 
PQclear(res);
 
res = PQexec(conn,"FETCH ALL in myportal");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
 fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
 PQclear(res);
 exit_nicely(conn);
}
 
//--------------------------------------ここからデータベースにアクセスする部分
/* 最初に,属性名を印刷する */
nFields = PQnfields(res); // フィールドの数を取得する
for (i=0; i < nFields; i++) { // 全てのフィールドを表示する
 printf("%-15s",PQfname(res,i));
}
printf("\n");
 
/* 次に,インスタンスを印刷する */
for (i=0; i < PQntuples(res); i++) { // 全ての行の..
 for (j=0 ; j < nFields; j++) { // 取得したフィールドを表示する
  printf("%-15s", PQgetvalue(res,i,j));
 }
 printf("\n");
}
 
// test makiyama------------------------
printf(PQgetvalue(res, 1,1));
printf("\n");
//-------------------------------------
printf("\n");
printf("\n");
//☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ここに追加
 
//--------------------------------------データベースにアクセスする部分終わり
 
PQclear(res);
 
/* 入口を閉じる */
res = PQexec(conn, "CLOSE myportal");
PQclear(res);
 
/* トランザクションを終る */
res = PQexec(conn, "END");
PQclear(res);
 
/* データベースへの接続を閉じる */
PQfinish(conn);
 
/* fclose(debug); */
}