Empress Embedded の使用例

C言語によるプログラミング（2）――レコード，バルク・データ章
7
第David Zhang
第 6 章に引き続き，C 言語インターフェースを使ったデータベース・プログラミングの実例について解説する．ここでは，レコードに対する操作を解説したあと，データのロック，データの整合性を保証するためのトランザクション処理の実例，ストリーミング・データなどを扱えるバ
ルク・データの扱いについて解説する．
（編集部）

本稿では，レコードに対する操作，ロック，トランザクショ

重複値を入力したり，ロックがかけられる場合）には，mrtput

ン，表現式の詳細，バルク・データの扱いについて解説します．

関数を使用してください．この関数は，失敗したときに false

1を，成功したときに true を返します．

レコードに対する操作

これらの関数の一般的な形式を以下に示します．
mrcopyr (new_rec_desc, old_rec_desc);● レコードの削除

mrput (new_rec_desc, old_rec_desc);

mrdel 関数と mrtdel 関数は，引き数にレコード記述子を指flag = mrtput (new_rec_desc, old_rec_desc);

定し，レコードを削除します．mrdel 関数は，削除に失敗した

リスト 2 は loans テーブル内のローンについて 2 ％の利子を場合に呼び出しプログラムを終了します．mrtdel 関数は，削計算し，借りている額と利子を表示します．また，現在額に利除に失敗した場合に false を，成功した場合に true を返します．

子を追加し，新しい合計を表示し，レコードを更新します．

通常，レコードは削除前に検索されます．対象レコードは，● 後で使用するレコードの保存

mrgetbegin 関数と検索条件関数により初期化され，mrgetアプリケーション・プログラムでは，異なる箇所で同一のレ関数で特定されます．すべての削除が完了した場合には，コードに異なった操作を行わなくてはならない場合があります．

Empress の内部バッファからファイルへ書き込むために，mrdelend 関数を呼び出す必要があります．
レコードを削除する一般的な形式を以下に示します．

リスト 1 レコードを削除する（delete.c）#include<mscc.h>flag = mrtdel (record_desc);#defineDATABASE

mrdelend (record_desc);msmain (){addr

mrdel (record_desc);

リスト 1 は 1992 年 5 月より前に作成されたレコードを削除します．

addr
char*

● レコードの更新"repairs"

loans_tabdesc, date_attrdesc,
loans_recdesc;qual, retrieve_desc;
date_value;

日付との比較

loans_tabdesc = mropen (DATABASE, "loans", 'u');

レコードを更新するには，二つのレコード記述子を取得する

loans_recdesc = mrmkrec (loans_tabdesc);
date_attrdesc = mrngeta (loans_tabdesc, "date");qual = mrqcon ("<", date_attrdesc,mrcvt (date_attrdesc, "1 May 1992"));

必 要 が あ り ま す ． 最 初 の レ コ ー ド 記 述 子（ 更 新 前 用 ）は ，mrmkrec 関数によって取得します．次のレコード記述子（更新後用）は，mrcopyr 関数によって，更新前用レコード記述子を

retrieve_desc = mrgetbegin(qual, loans_recdesc, ADDRNIL);
while (mrget (retrieve_desc))
mrdel (loans_recdesc);

コピーして作成します．この関数は，引き数に二つのレコード記述子を指定します．更新後用のレコード内のフィールド値は，レコードの追加処理と同じように，mrputvs 関数，mrputvi

mrgetend (retrieve_desc);関数などを使用して変更します．レコードの更新は，mrput 関

mrdelend (loans_recdesc);

数を呼び出して行われます．この関数は，引き数に更新前，更mrfrrec (loans_recdesc);

新後のレコード記述子を指定します．

mrclose (loans_tabdesc);

更新が失敗する可能性がある場合（ユニークなフィールドにDec. 2006}

KEYWORD ―― レコード，バルク・データ，Perl，Tcl/Tk，トランザクション，レコード・ポインタ，
レコード・レベル・ロック，データ・ストリーミング

99リスト 2 レコードの更新（interest.c）#include<mscc.h>#defineDATABASE"repairs"

externdoubledollcvt ();msmain ()
{
addr

addr
addr
double
char*
char*
char*
char*
char

mrcopyv (loans_recdesc, date_attrdesc,date_value);amount = dollcvt (amount_value);interest = amount * 0.02;
利子の計算
newamount = amount + interest;
sum = sum + newamount;
printf ("$%-6.2f %s$%-6.2f $%-6.2f¥n",amount, date_value, interest, newamount);loans_tabdesc, pers_tabdesc,
loans_recdesc, pers_recdesc,new_recdesc;
pname_attrdesc, lname_attrdesc,
date_attrdesc, amount_attrdesc;qual, p_retrieve_desc,
l_retrieve_desc;
amount, sum, newamount, interest;
name;pname_value;
date_value;amount_value;
value[20];mrcopyr (new_recdesc, loans_recdesc);
sprintf (value, "$%-6.2f", newamount);
if (mrputvs (new_recdesc, amount_attrdesc,value))
mrput (new_recdesc, loans_recdesc);
else
fprintf (stderr, "Cannot convert¥
newamount '%-6.2f'¥n¥Update not done for %s %s¥%-6.2f¥n", newamount,pname_value, date_value, amount);loans_tabdesc = mropen (DATABASE, "loans", 'u');pers_tabdesc = mropen (DATABASE, "personnel", 'r');}mrgetend (l_retrieve_desc);loans_recdesc = mrmkrec (loans_tabdesc);
new_recdesc = mrmkrec (loans_tabdesc);
pers_recdesc = mrmkrec (pers_tabdesc);

if (sum > 0)
printf ("¥nTotal now owing: $%-6.2f¥n", sum);
else
printf ("¥nNo loans outstanding.¥n");レコード
記述子の取得}mrgetend (p_retrieve_desc);

pname_attrdesc = mrngeta (pers_tabdesc, "name");lname_attrdesc = mrngeta (loans_tabdesc, "name");amount_attrdesc = mrngeta (loans_tabdesc, "amount");
date_attrdesc = mrngeta (loans_tabdesc, "date");mrfree (pname_value);
mrfree (date_value);
mrfree (amount_value);mrfrrec (loans_recdesc);
mrfrrec (new_recdesc);
mrfrrec (pers_recdesc);amount_value = mrspv (amount_attrdesc);
pname_value = mrspv (pname_attrdesc);
date_value = mrspv (date_attrdesc);p_retrieve_desc = mrgetbegin (ADDRNIL, pers_recdesc,ADDRNIL);
while (mrget (p_retrieve_desc))
レコード記述子のコピー{
mrcopyv (pers_recdesc, pname_attrdesc, pname_value);
printf ("¥n¥nMonthly Statement for %s:¥n¥n",pname_value);
printf ("Loan
Date Made
Interest Total¥n");sum = 0;qual = mrqcon ("=", lname_attrdesc,mrcvt (lname_attrdesc, pname_value));l_retrieve_desc = mrgetbegin (qual, loans_recdesc,ADDRNIL);
while (mrget (l_retrieve_desc)){
mrcopyv (loans_recdesc, amount_attrdesc,amount_value);

一度レコードを検索したら，以下に示すことが行えます．

mrclose (loans_tabdesc);
mrclose (pers_tabdesc);}/* strip $ , * space from dollar amounts */double dollcvt (char* string){externdouble
atof ();
charc, buffer [20];char*buf_ptr;for (buf_ptr = buffer ; (c = *string++) != '¥0' ; )if (c != '$' && c != '*' && c != ' ' && c != ',')
*buf_ptr++ = c;*buf_ptr = '¥0';
return (atof (buffer));}

へのレコード保存は有用です．

¡直接操作できるように，そのレコードをメモリに保存するレコード記述子をコピーするには，mrmkrec 関数を呼び出¡以降の検索で，検索条件を構築しなくてもよいように，そのして新しいレコード記述子を取得し，レコードの更新と同じよレコードへのポインタを保存する

うに，mrcopyr 関数によって新しいレコード記述子にコピーレコード値が変更された場合，変更前の検索条件ではレコーします．これによってレコードがメモリ内にコピーされ，テードを再検索できないので，レコードまたはポインタを保存する

ブルから再検索することなく，いつでもアクセス可能となりまことが非常に役にたちます．

す（通常は，検索ループの中で現在のレコードが後で必要にな● メモリへのレコード保存ると判断された場合に実行される）．保存されたレコード記述レコードをメモリ内に保存する際には，そのレコードのレ子は，後のプログラム内でいつでも，mrcopyv 関数などの検コード記述子をコピーすることになります．この場合，スペー索関数の一つに受け渡すことが可能です．レコードに対する処スを使い過ぎないように，数レコードにしぼって実行してくだ理が完了したら，mrfrrec 関数を使用してスペースを解放しさい．レコードがロック状態で保たれている場合にも，メモリてください．

100

New Products ―― アクシスソフト，OS の種類に依存しない Web 帳票印刷ツールを発売
アクシスソフトは，Java が動作する環境で使用する Web 帳票印刷ツール「PrintStream Core」を発売した．Windows や Linux といった OS の種類に関係なく利用できる．

Dec. 2006