フリーウエア利用2 SQLite
SQLite(エスキューライト)は、C言語で利用できる組み込み用のSQLデータベースエンジンです。SQLiteのHPで以下のように紹介されています。
「C言語のライブラリでできた、小型・高速の組み込み型のSQLデータベースエンジンであり、高信頼性とフルSQL機能を持っている。SQLiteは、すべてのスマホ、PCに実装可能であり、アプリに制約なく組み込める。SQLiteデータベース・ファイルは、プラットフォームに依存せず、過去のデータも読み込み可能で、開発者は将来にわたって使い続けることができる。
SQLiteデータベース・ファイルはシステム間で大容量のファイルの転送に使われる。データのアーカイブ・ファーマットとしても使われ、1テラ以上のSQLiteのデータベースも存在する」
Embarcadero C++ Compiler で利用する場合の手順、プログラムへの組込み方を紹介します。
1)ソフトの入手
ソフトは、SQLitのHP(https://www.sqlite.org/download.html)からダウンロードします。
SQLiteを紹介したサイトがあります(例 https://www.dbonline.jp/sqlite/)ので、具体的な操作は、そちらを参照ください。
2020年4月現在で、バージョンは、Version 3.31.1 (2020-01-27)で、取得すべきファイルは以下になります。
@sqlite-dll-win32-x86-3310100.zip (32-bit DLL (x86) for SQLite)
ここに、splite3.dllが含まれています。このDLLから、ライブラリファイル(.Lib)を作成します。64ビット版もあるのですが、C++コンパイラが32ビット版ですので32ビット版を使います。
Asqlite-tools-win32-x86-3310100.zip
ここには、SQLiteを操作するコマンドライン・ツールである、Sqlite3.exeが含まれます。ファイルの確認、テーブルの確認、データ内容の確認を行うので、必要です。
Bsqlite-autoconf-3310100.tar.gz
こちらは、種々のプログラム・ソースコードがあります、Embarcadero C++ のプログラムを開発を行うにあたって、ヘッダ・ファイル(SQLite3.h)を使います。
必要なファイルを特定のフォルダ(例:C:\borland\program\freeware2 )に保管します。
2)著作権
SQLiteのソースコードは、パブリックドメインで、ヘッダー・ファイルに、以下が書かれています。
「作者はソースコードの著作権を放棄し、その記載の代わりに祈りを記します。
あなたが、善を行い、悪を行わないことを
また、自分自身への許しをみつけ、他人を許すことを
そして、自由に共有し、自分が得たもの以上を取らないことを祈ります」
有用なソフトの公開を感謝します。更新が都度行われますので、このHPでは、SQLiteのヘッダ・ファイル、dllは、置いていません、作者のサイトから取得お願いします。
3)ライブラリの作成
Embarcadero C++ Compilerのコマンドライン ツールのimplib.exeを使って、上記のSQLite3.dllからライブラリ(sqlite3.lib)を作成します。
実行結果は以下の@です。
@ライブラリ作成

1)動作確認プログラム(sqlite_01.c)
ヘッダーファイル(SQLite.h)をインクルードし、SQLite.libを組み込んだ実行ファイルを作成します。内容は、SQLITEのバージョン(定数 SQLITE_VERSION)を表示するだけのものです。
ソースプログラムがA、コンパイル結果はB、プログラムの実行結果はCです。
コンパイル方法は、これ以降のサンプルプログラムでは「SQLite_0X」のXをソース・ファイル名に合わせて変更すれば良いので、以下は省略しています。
Aソースファイル
// -------------------------------------------------
// sqlite_01.c SQLite テストプログラム1
// ・「sqlite3.h」の include
// ・「sqlite3.lib」の リンク
// 2020/04/10 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include "sqlite3.h"
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
fprintf(stdout, "SQLite version = %s\n", SQLITE_VERSION);
return 0;
}
Bコンパイル結果

C実行結果

SQLiteのAPIである、sqlite3_open関数を使用して、新規のデータベース・ファイル(ファイル名、batting.db)を作成します。ここでは、サイズが0の空のファイルが作成されます)
ソースプログラムが@、プログラムの実行結果はAです。
【データベース・ハンドル】 sqlite3 *db
・機能 SQLiteデータベースに接続するために使う。
|
【関数名】int sqlite3_open( const char *filename , sqlite3 **db);
int sqlite3_open_v2( const char *filename , sqlite3 **db , int flags
, const char *zVfs );
・機能 SQLiteデータベースを作成、オープンする。
・引数 *filename :ファイル名(UTF-8)
**db :SQLite データベースハンドル
flags :SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE オープン・なければ作成
SQLITE_OPEN_READONLY
SQLITE_OPEN_READWRITE
*zVfs : 使用する VFS モジュール名( 指定しない場合はNULL)
・戻り値 SQLITE_OK :OK
その他は現エラー
・備考 sqlite3_open_v2()は、オープン・作成のモードを持つ。
sqlite3_open()は、「SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE」で設定。
|
【関数名】int sqlite3_close(sqlite3 *db )
int sqlite3_close_v2(sqlite3 *db)
・機能 SQLiteデータベースをクローズする。
・引数 sqlite3 *db データベースハンドル
・戻り値 SQLITE_OK :0(OK)
その他は現エラー
・備考 |
@ソースプログラム(sqlite_02.c)
// -------------------------------------------------
// sqlite_02.c SQLite テストプログラム2
// ・ファイル作成
// 2020/04/10 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "sqlite3.h"
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db;
char *db_name= "batting.db";
int rc; // 結果
// データベースファイルを新規生成 or オープン
rc = sqlite3_open(db_name, &db);
fprintf(stdout, "Open status:[%s] [%s]\n", db_name, sqlite3_errmsg(db));
return 0;
}
A実行結果

作成した、データベース・ファイル(batting.db)にSQL文(create table テーブル名 (テーブル定義))を実行してテーブルを設定します。sqlite3_exec関数の2番目の引数にSQL文を指定して、実行します。
ここでは、自作ソフトの紹介1-2と同様にプロ野球の打撃成績を例にしたテーブルを作成します。
ソースプログラムが@、プログラムの実行結果はAです。保管できる日本語のコードはunicodeとなりますが、元のデータがWindowsのSJISコードで、変換が必要となるので、英語(1バイトコード)の名前とチーム名を使っています。
【関数名】int sqlite3_exec( sqlite3 *db , const char *sql ,
int (*callback ) ( void* , int , char** ,char** ), void * , char
**errmsg );
・機能 SQLiteデータベースにSQL文を実行する。
・引数 sqlite3 *db :データベースハンドル
*sql :SQL文
callback:コールバック関数 、必要なければNULLとする。
void* :コールバック関数の第1引数に渡す。
**errmsg :エラーメッセージ
・戻り値 SQLITE_OK :0(OK)、エラーメッセージはNULLとなる。
その他は現エラー
・備考
|
@ソースプログラム(sqlite_03.c)
// -------------------------------------------------
// sqlite_03.c SQLite テストプログラム3
// ・テーブル作成
// 2020/04/12 Kimio Nakamura
// -------------------------------------------------
// ===== テーブル CL_batting_2019 ====
// 順位 no INTEGER
// 選手 name TEXT
// 球団 team TEXT
// 打率 batting_average REAL
// 打数 at_bat INTEGER
// 安打 hit INTEGER
// 本塁打 home_run INTEGER
// 打点 run INTEGER
// 三振 strikeout INTEGER
// 併殺打 double_play INTEGER
// 長打率 extra_base_percentage REAL
// 出塁率 on_base_percentage REAL
//
#include <stdio.h>
#include <string.h>
#include "sqlite3.h"
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db; //
char *db_name = "batting.db";
char *table_name = "batting_2019";
char *table = "no INTEGER, name TEXT, team TEXT,"
batting_average REAL, "
"at_bat INTEGER, hit INTEGER , home_run INTEGER ,"
run INTEGER , strikeout INTEGER , double_play INTEGER,"
extra_base_percentage REAL ,on_base_percentage REAL";
char *error_message;
char sql_statement[2000];
int rc; // 結果
// データベースファイルをオープン
rc = sqlite3_open( db_name , &db);
fprintf(stdout, "Open/Create status:[%s] [%s]\n", db_name,
sqlite3_errmsg(db));
// テーブル作成、SQLステートメントを作成
sprintf(sql_statement, "create table %s(%s)", table_name, table);
// SQLステートメントを実行
rc = sqlite3_exec(db, sql_statement, NULL, NULL, &error_message);
if(rc == SQLITE_OK){
fprintf(stdout, "Exec(Ceate Table):%s\n", sqlite3_errmsg(db));
}
else fprintf(stdout, "ERROR(Ceate Table):%s\n", error_message);
sqlite3_close(db); // クローズ
return 0;
}
A実行結果

データベース・ファイル(batting.db)にSQL文(insert into テーブル名 values(レコード・データ))をsqlite3_exec関数で実行して、データベースに登録します。
ソースプログラムが@で、プログラムの実行結果がAです。正常に登録できたので、エラーメッセージが「null」になっています。
@ソースプログラム(sqlite_04.c)
// -------------------------------------------------
// sqlite_04.c SQLite テストプログラム4
// ・データ入力
// 2020/04/17 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "sqlite3.h"
typedef struct
{
long no; // 1 順位
char name[30]; // 2 選手
char team[30]; // 3 球団
double batting_average; // 4 打率
long at_bat; // 5 打数
long hit; // 6 安打
long home_run; // 7 本塁打
long run; // 8 打点
long strikeout; // 9 三振
long double_play; // 10 併殺打
double extra_base_percentage; // 11 長打率
double on_base_percentage; // 12 出塁率
}BATTING;
BATTING batting[50] = {
{1 ,"Suzuki,Seiya","(C)",0.335 ,499 ,167 ,28 ,87 ,81 ,3 ,0.565 ,0.453},
{2 ,"Viciedo,Dayan","(D)",0.315 ,534 ,168 ,18 ,93 ,88 ,22 ,0.496 ,0.374},
{3 ,"Itoi,Yoshio","(T)",0.314 ,382 ,120 ,5 ,42 ,63 ,10 ,0.416 ,0.403},
{4 ,"Oshima,Yohei","(D)",0.312 ,558 ,174 ,3 ,45 ,78 ,5 ,0.38 ,0.376},
{5 ,"Sakamoto,Hayato","(G)",0.312 ,555 ,173 ,40 ,94 ,123 ,9 ,0.575 ,0.396},
{6 ,"Nishikawa,Ryoma","(C)", 0.297 ,535 ,159 ,16 ,64 ,81 ,9 ,0.441 ,0.336},
{7 ,"Aoki,Norichika","(S)", 0.297 ,489 ,145 ,16 ,58 ,72 ,13 ,0.442 ,0.385},
{8 ,"Takahashi,Shuhei","(D)", 0.293 ,430 ,126 ,7 ,59 ,70 ,10 ,0.43 ,0.345},
{9 ,"Maru,Yoshihiro","(G)",0.292 ,535 ,156 ,27 ,89 ,125 ,15 ,0.495 ,0.388},
{10,"Abe,Toshiki","(D)",0.291 ,447 ,130 ,7 ,59 ,82 ,9 ,0.405 ,0.337},
{11,"Kamei,Yoshiyuki","(G)",0.284 ,450 ,128 ,13 ,55 ,91 ,6 ,0.44 ,0.346},
{12,"Miyazaki,Toshiro","(DB)",0.284 ,433 ,123 ,15 ,49 ,35 ,13 ,0.443 ,0.334},
{13,"Balentien,Wladimir","(S)",0.28 ,410 ,115 ,33 ,93 ,117 ,11 ,0.554 ,0.363},
{14,"Kamizato,Kazuki","(DB)",0.279 ,427 ,119 ,6 ,35 ,121 ,7 ,0.407 ,0.323},
{15,"Aizawa,Tsubasa","(C)",0.277 ,376 ,104 ,12 ,63 ,81 ,6 ,0.439 ,0.387},
{16,"Takai,Yuhei","(S)",0.273 ,447 ,122 ,12 ,56 ,71 ,4 ,0.396 ,0.327},
{17,"Tsutsugo,Yoshitomo","(DB)",0.272 ,464 ,126 ,29 ,79 ,141 ,5 ,0.511 ,0.388},
{18,"Chikamoto,Koji","(T)",0.271 ,586 ,159 ,9 ,42 ,110 ,2 ,0.375 ,0.313},
{19,"Yamada,Tetsuto","(S)",0.271 ,520 ,141 ,35 ,98 ,121 ,14 ,0.56 ,0.401},
{20,"Soto,Neftali","(DB)",0.269 ,516 ,139 ,43 ,108 ,98 ,14 ,0.554 ,0.348},
{21,"Nakamura,Yuhei","(S)",0.269 ,372 ,100 ,5 ,36 ,64 ,11 ,0.384 ,0.373},
{22,"Itohara,Kento","(T)",0.267 ,491 ,131 ,2 ,45 ,70 ,7 ,0.336 ,0.353},
{23,"Umeno,Ryutaro","(T)",0.266 ,433 ,115 ,9 ,59 ,83 ,16 ,0.393 ,0.326},
{24,"Okamoto,Kazuma","(G)",0.265 ,555 ,147 ,31 ,94 ,132 ,15 ,0.485 ,0.343},
{25,"Kikuchi,Ryosuke","(C)",0.261 ,547 ,143 ,13 ,48 ,102 ,5 ,0.406 ,0.313},
{26,"Oyama,Yusuke","(T)",0.258 ,538 ,139 ,14 ,76 ,98 ,12 ,0.401 ,0.312},
{27,"Kyoda,Yota","(D)",0.249 ,507 ,126 ,3 ,40 ,91 ,10 ,0.314 ,0.302},
{28,"Lopez,Jose","(DB)",0.241 ,551 ,133 ,31 ,84 ,107 ,18 ,0.461 ,0.295},
{29,"Maeda,Yamato","(DB)",0.237 ,438 ,104 ,0 ,37 ,75 ,7 ,0.285 ,0.3},
{30,"Murakami,Munetaka","(S)",0.231 ,511 ,118 ,36 ,96 ,184 ,9 ,0.481 ,0.332}};
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db; //
char *db_name = "batting.db";
char *table_name = "batting_2019";
char *error_message;
char sql_statement[2000];
int rc; // 結果
int i;
// データベースファイルをオープン
rc = sqlite3_open( db_name , &db);
fprintf(stdout, "Open/Create status:[%s] [%s]\n", db_name, sqlite3_errmsg(db));
// データ入力
for(i=0 ; i<30; i++){
sprintf(sql_statement,"insert into %s values(%ld,'%s','%s',%lf,%ld,%ld,
%ld,%ld,%ld,%ld,%lf,%lf)",
table_name,
batting[i].no , batting[i].name , batting[i].
team,batting[i].batting_average , batting[i].at_bat, batting[i].hit ,
batting[i].home_run , batting[i].run, batting[i].strikeout ,
batting[i].double_play ,batting[i].extra_base_percentage ,
batting[i].on_base_percentage);
rc =sqlite3_exec(db, sql_statement, 0, 0, &error_message);
fprintf(stdout ,"%d %d %s\n",i , rc , error_message);
}
return 0;
}
A実行結果

データベース・ファイル(batting.db)からSQL文(select * from テーブル名)をsqlite3_exec関数で実行して、データベースを検索します。結果を得るための3番目の引数にcallback関数を登録します。callback関数には、取得したデータを表示する処理を入れておきます。
ソースプログラムが@、プログラムの実行結果はAです。実行結果から分かるように、1件検索したらcallback関数が呼ばれます。
【関数名】int callback (void* , int argc , char **argv , char **col );
・機能 sqlite3_execの中で呼び出される関数を設定できる。
・引数 void* :sqlite3_execの4番目の引数が渡される。
argc :件数
**argv :検索された内容(argc 分)
**col :列名(argc 分)
・戻り値 0(OK)
0以外の場合は、中断し、sqlite3_execでSQLITE_ABORT(4)が返す。
・備考
|
Bは、SQLiteコマンドライン・ツール(sqlite3.exe)を使って、これまで実行した内容が、データベースに正しく反映されているか調べます。「.open」コマンド、「.databases」コマンドでデータベース・ファイルのオープン、ファイル名を調べます。「.schema」コマンドで、テーブル内容を表示します。SQL文(select * from batting_2019;)で、内容を表示します。
@ソース・プログラム(sqlite_05.c)
// -------------------------------------------------
// sqlite_05.c SQLite テストプログラム5
// ・データ表示
//
// 2020/04/19 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "sqlite3.h"
// =========================================================================
// Name : int callback(void *NotUsed, int argc, char *argv[], char *ColName[])
// Usage : 抽出結果が返るコールバック関数
// Parameter: 1番目:未使用、2番目:argc データ数、3番目 *argv[] データ
// 4番目:*ColName[] カラム名
// Return :
// =========================================================================
int callback(void *NotUsed, int argc, char *argv[], char *ColName[]){
int i;
for(i = 0; i < argc; i++){
fprintf(stdout , "%-25s = %s\n", ColName[i], argv[i]);
}
fprintf(stdout , "\n");
return 0;
}
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db;
char *db_name = "batting.db";
char *table_name = "batting_2019";
char sql_statement[2000];
char *error_message;
int rc; // 結果
// データベースファイルをオープン
rc = sqlite3_open( db_name , &db);
fprintf(stdout, "Open status:[%s] [%s]\n", db_name, sqlite3_errmsg(db));
// テーブルの全項目を列挙
sprintf( sql_statement, "select * from %s", table_name);
rc = sqlite3_exec(db, sql_statement, callback, 0, &error_message);
fprintf(stdout, "select status:[%d] [%s]\n", rc, error_message);
return 0;
}
A実行結果

BSQLite.exeでの確認

5)のデータ表示と同様の内容ですが、sqlite3_exec関数の4番の引数に、検索データを保管する構造体のアドレスを引き渡します。このアドレスは、callback関数の1番目の引数に引き渡されます。
callback関数の中で、引き渡された構造体アドレスを使って、検索した情報を保管する。
@がソースプログラム、プログラムの実行結果はAです。
@ソース・プログラム(sqlite_13.c)
// -------------------------------------------------
// sqlite_13.c SQLite テストプログラム
// ・データ読み込み・・・行単位、callbackを使う
// sql3_exec 関数から callback関数に渡されて
// きたアドレスを使う。
// 2020/05/05 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sqlite3.h"
#define MAX_REC 100 // batting 構造体の最大数
typedef struct
{
long no; // 1 順位
char name[30]; // 2 選手
char team[30]; // 3 球団
double batting_average; // 4 打率
long at_bat; // 5 打数
long hit; // 6 安打
long home_run; // 7 本塁打
long run; // 8 打点
long strikeout; // 9 三振
long double_play; // 10 併殺打
double extra_base_percentage; // 11 長打率
double on_base_percentage; // 12 出塁率
}BATTING;
BATTING batting[MAX_REC];
int batting_table_num = 12; // batting テーブルの項目数
int batting_rec_num ; // batting 検索件数
//------------------------プロトタイプ宣言-----------------
// =========================================================================
// Name : int callback(void * , int argc, char *argv[], char *ColName[])
// Usage : 抽出結果が返るコールバック関数
// Parameter: 1番目:void *、2番目:argc データ数、3番目 *argv[] データ
// 4番目:*ColName[] カラム名
// Return : 0 OK
// =========================================================================
int callback_select3( void *tb, int argc, char *argv[], char *ColName[]){
int i ;
BATTING *ptb[MAX_REC];
for (i= 0; i<MAX_REC ; i++){
ptb[i] = tb + i * sizeof(BATTING);
}
for(i = 0; i < argc; i++){
if( strcmp( ColName[i], "no") == 0 )
ptb[batting_rec_num]->no = atol(argv[i]);
else if ( strcmp( ColName[i], "name") == 0 )
strcpy(ptb[batting_rec_num]->name , argv[i]);
else if ( strcmp( ColName[i], "team") == 0 )
strcpy(ptb[batting_rec_num]->team , argv[i]);
else if ( strcmp( ColName[i], "batting_average") == 0 )
ptb[batting_rec_num]->batting_average = atof( argv[i] );
else if ( strcmp( ColName[i], "at_bat") == 0 )
ptb[batting_rec_num]->at_bat = atol( argv[i] );
else if ( strcmp( ColName[i], "hit") == 0 )
ptb[batting_rec_num]->hit = atol( argv[i] );
else if ( strcmp( ColName[i], "home_run") == 0 )
ptb[batting_rec_num]->home_run = atol( argv[i] );
else if ( strcmp( ColName[i], "run") == 0 )
ptb[batting_rec_num]->run = atol( argv[i] );
else if ( strcmp( ColName[i], "strikeout") == 0 )
ptb[batting_rec_num]->strikeout = atol( argv[i] );
else if ( strcmp( ColName[i], "double_play" ) == 0 )
ptb[batting_rec_num]->double_play = atol( argv[i] );
else if ( strcmp( ColName[i], "extra_base_percentage") == 0 )
ptb[batting_rec_num]->extra_base_percentage = atof( argv[i] );
else if ( strcmp( ColName[i], "on_base_percentage") == 0 )
ptb[batting_rec_num]->on_base_percentage = atof( argv[i] );
}
batting_rec_num++;
return 0;
}
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db;
char *db_name = "batting.db";
char *table_name = "batting_2019";
char sql_statement[2000];
char *error_message;
int rc; // 結果
int i=1;
// データベースファイルをオープン
rc = sqlite3_open( db_name , &db);
fprintf(stdout, "Open/Create status:[%s] [%s]\n",
db_name, sqlite3_errmsg(db));
// テーブルの全項目を列挙
batting_rec_num =0;
sprintf( sql_statement, "select * from %s", table_name);
rc = sqlite3_exec(db, sql_statement, callback_select3 ,
&batting[0] , &error_message);
fprintf(stdout, "select status:[%d] [%s]\n", rc, error_message);
for (i=0; i < batting_rec_num ; i++){
fprintf(stdout,"%2d %2ld %20s %5s %1.3lf %3ld %3ld %3ld
%3ld %3ld %3ld %1.3lf %1.3lf\n",
i,
batting[i].no , batting[i].name , batting[i].team,
batting[i].batting_average ,
batting[i].at_bat,batting[i].hit , batting[i].home_run ,
batting[i].run,
batting[i].strikeout , batting[i].double_play ,
batting[i].extra_base_percentage ,
batting[i].on_base_percentage);
}
rc = sqlite3_close( db );
return 0;
}
A実行結果

SQLiteのデータタイプは、INTEGER(整数)、REAL(実数)、TEXT(文字型)、BLOB(入力したまま)です。TEXT型はUNICODE(UTF-16、UTF-8)となり、Windowsで使われるSJISは、UTF8に変換して使います。変換にはNKF(Network KANJI Filter)を使います。NKFは「フリーウェアの利用3、NKF」を参照ください。
SQLiteデータベース(batting_utf8.db)を作成、テーブルをbatting_utf8_2019で作成し、データの登録、読み込んで表示するまでを行います。
@が、ソースプログラム、Aが、プログラムの実行結果です。
@ソースプログラム(sqlite_08.c)
// -------------------------------------------------
// sqlite_08.c SQLite テストプログラム
// ・データ入力・・・SJIS->UTF8
// 2022/02/05 Kimio Nakamura
// -------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "sqlite3.h"
#include "nkf32.h"
typedef struct
{
long no; // 1 順位
char name[30]; // 2 選手
char team[30]; // 3 球団
double batting_average; // 4 打率
long at_bat; // 5 打数
long hit; // 6 安打
long home_run; // 7 本塁打
long run; // 8 打点
long strikeout; // 9 三振
long double_play; // 10 併殺打
double extra_base_percentage; // 11 長打率
double on_base_percentage; // 12 出塁率
}BATTING;
BATTING batting[50] = {
{1 , "鈴木 誠也" ,"(広)" , 0.335 , 499 , 167 , 28 , 87 , 81 , 3 , 0.565 , 0.453},
{2 , "ビシエド" , "(中)" , 0.315 , 534 , 168 , 18 , 93 , 88 , 22 , 0.496 , 0.374},
{3 , "糸井 嘉男" , "(神)" , 0.314 , 382 , 120 , 5 , 42 , 63 , 10 , 0.416 , 0.403},
{4 , "大島 洋平" , "(中)" , 0.312 , 558 , 174 , 3 , 45 , 78 , 5 , 0.38 , 0.376},
{5 , "坂本 勇人" , "(巨)" , 0.312 , 555 , 173 , 40 , 94 , 123 , 9 , 0.575 , 0.396},
{6 , "西川 龍馬" , "(広)" , 0.297 , 535 , 159 , 16 , 64 , 81 , 9 , 0.441 , 0.336},
{7 , "青木 宣親" , "(ヤ)" , 0.297 , 489 , 145 , 16 , 58 , 72 , 13 , 0.442 , 0.385},
{8 , "高橋 周平" , "(中)" , 0.293 , 430 , 126 , 7 , 59 , 70 , 10 , 0.43 , 0.345},
{9 , "丸 佳浩" , "(巨)" , 0.292 , 535 , 156 , 27 , 89 , 125 , 15 , 0.495 , 0.388},
{10 , "阿部 寿樹" , "(中)" , 0.291 , 447 , 130 , 7 , 59 , 82 , 9 , 0.405 , 0.337},
{11 , "亀井 善行" , "(巨)" , 0.284 , 450 , 128 , 13 , 55 , 91 , 6 , 0.44 , 0.346},
{12 , "宮ア 敏郎" , "(デ)" , 0.284 , 433 , 123 , 15 , 49 , 35 , 13 , 0.443 , 0.334},
{13 , "バレンティン" , "(ヤ)" , 0.28 , 410 , 115 , 33 , 93 , 117 , 11 , 0.554 , 0.363},
{14 , "神里 和毅" , "(デ)" , 0.279 , 427 , 119 , 6 , 35 , 121 , 7 , 0.407 , 0.323},
{15 , "會澤 翼" , "(広)" , 0.277 , 376 , 104 , 12 , 63 , 81 , 6 , 0.439 , 0.387},
{16 , "雄平" , "(ヤ) ", 0.273 , 447 , 122 , 12 , 56 , 71 , 4 , 0.396 , 0.327},
{17 , "筒香 嘉智" , "(デ)" , 0.272 , 464 , 126 , 29 , 79 , 141 , 5 , 0.511 , 0.388},
{18 , "近本 光司" , "(神)", 0.271 , 586 , 159 , 9 , 42 , 110 , 2 , 0.375 , 0.313},
{19 , "山田 哲人" , "(ヤ)" , 0.271 , 520 , 141 , 35 , 98 , 121 , 14 , 0.56 , 0.401},
{20 , "ソト" , "(デ)" , 0.269 , 516 , 139 , 43 , 108 , 98 , 14 , 0.554 , 0.348},
{21 , "中村 悠平" , "(ヤ)" , 0.269 , 372 , 100 , 5 , 36 , 64 , 11 , 0.384 , 0.373},
{22 , "糸原 健斗" , "(神)" , 0.267 , 491 , 131 , 2 , 45 , 70 , 7 , 0.336 , 0.353},
{23 , "梅野 隆太郎" , "(神)" , 0.266 , 433 , 115 , 9 , 59 , 83 , 16 , 0.393 , 0.326},
{24 , "岡本 和真" , "(巨)" , 0.265 , 555 , 147 , 31 , 94 , 132 , 15 , 0.485 , 0.343},
{25 , "菊池 涼介" , "(広)" , 0.261 , 547 , 143 , 13 , 48 , 102 , 5 , 0.406 , 0.313},
{26 , "大山 悠輔" , "(神)" , 0.258 , 538 , 139 , 14 , 76 , 98 , 12 , 0.401 , 0.312},
{27 , "京田 陽太" , "(中)" , 0.249 , 507 , 126 , 3 , 40 , 91 , 10 , 0.314 , 0.302},
{28 , "ロペス" , "(デ)" , 0.241 , 551 , 133 , 31 , 84 , 107 , 18 , 0.461 , 0.295},
{29 , "大和" , "(デ)" , 0.237 , 438 , 104 , 0 , 37 , 75 , 7 , 0.285 , 0.3},
{30 , "村上 宗隆" , "(ヤ)" , 0.231 , 511 , 118 , 36 , 96 , 184 , 9 , 0.481 , 0.332}
};
// =========================================================================
// Name : int callback(void *NotUsed, int argc, char *argv[], char *ColName[])
// Usage : 抽出結果が返るコールバック関数
// Parameter: 1番目:未使用、2番目:argc データ数、3番目 *argv[] データ
// 4番目:*ColName[] カラム名
// Return :
// =========================================================================
int callback(void *NotUsed, int argc, char *argv[], char *ColName[]){
int i;
// SJIS 変換用
char sjis_temp[200];
// NKF(SJIS-UTF-8変換設定)
SetNkfOption("-s");
for(i = 0; i < argc; i++){
if( strcmp( ColName[i] , "name" )==0 || strcmp( ColName[i] , "team" )==0) {
NkfConvert( sjis_temp , argv[i] );
fprintf(stdout , "%-25s = %s\n", ColName[i], sjis_temp );
}
else fprintf(stdout , "%-25s = %s\n", ColName[i], argv[i]);
}
fprintf(stdout , "\n");
return 0;
}
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
sqlite3 *db; //
char *db_name = "batting_utf8.db";
char *table_name = "batting_utf8_2019";
char *error_message;
char sql_statement[2000];
char *table = "no INTEGER, name TEXT, team TEXT, batting_average REAL, "
"at_bat INTEGER, hit INTEGER , home_run INTEGER , run INTEGER , "
"strikeout INTEGER , double_play INTEGER, extra_base_percentage REAL ,"
"on_base_percentage REAL";
int rc; // 結果
int i;
// UTF 変換用
char utf8_name[200];
char utf8_team[200];
// データベースファイルをオープン
rc = sqlite3_open( db_name , &db);
fprintf(stdout, "Open/Create status:[%s] [%s]\n", db_name, sqlite3_errmsg(db));
sprintf(sql_statement, "create table %s(%s)", table_name, table);
// SQLステートメントを実行
rc = sqlite3_exec(db, sql_statement, NULL, NULL, &error_message);
if(rc == SQLITE_OK) fprintf(stdout, "Exec(Ceate Table):%s\n", sqlite3_errmsg(db));
else fprintf(stdout, "ERROR(Ceate Table):%s\n", error_message);
// NKF(SJIS-UTF-8変換設定)
SetNkfOption("-w");
// データ入力
for(i=0 ; i<30; i++){
NkfConvert( utf8_name , batting[i].name);
NkfConvert( utf8_team , batting[i].team);
sprintf(sql_statement,"insert into %s values(%ld,'%s','%s',%lf,%ld,%ld,
%ld,%ld,%ld,%ld,%lf,%lf)",
table_name,
batting[i].no , utf8_name , utf8_team ,
batting[i].batting_average , batting[i].at_bat,
batting[i].hit , batting[i].home_run , batting[i].run,
batting[i].strikeout , batting[i].double_play ,
batting[i].extra_base_percentage , batting[i].on_base_percentage);
rc =sqlite3_exec(db, sql_statement, 0, 0, &error_message);
fprintf(stdout ,"%d %d %s\n",i , rc , error_message);
}
// テーブルの全項目を列挙・表示
sprintf( sql_statement, "select * from %s", table_name);
rc = sqlite3_exec(db, sql_statement, callback, 0, &error_message);
fprintf(stdout, "select status:[%d] [%s]\n", rc, error_message);
rc = sqlite3_close( db );
return 0;
}
A実行結果(部分)

SQLiteについては、次に続きます。

|