フリーウエア利用2 SQLite その2
SQLiteでは、SQL文をsqlite3_exec()関数で実行します。一括して処理を行い、個々の結果を扱うために、「callback」関数を介して行うことになります。細かなコントロールが難しいので、3つの関数(sqlite3_prepare()関数、sqlite3_step()関数、sqlite3_finalize()関数)で逐次実行できるようになっています。便利になる分、使う関数が増えます。手順としては、以下のようになります。
・sqlite3_stmt stmt ステートメント・ハンドル宣言
・SQL文の設定、外部からの設定ができるようにパラメータ(変数)を埋め込む。
・sqlite3_prepare_v2() ステートメント・ハンドルに、SQL文を設定する。
・sqlite3_bind_*() SQL文に外部からパラメータ(変数)を代入する。
・sqlite3_step() SQL文の実行
・sqlite3_column_*() column(列)毎の値の取得を行う。
・sqlite3_reset() ステートメント・ハンドルのクリア
・sqlite3_finalize() ステートメント・ハンドルの破棄
【ステートメント・ハンドル】 sqlite3_stmt* stmt
・機能 SQL文の処理と実行のために使う。 |
【SQL文とパラメータ(変数)】
SQL文にパラメータ(変数)を埋め込むことができます。
・? 他のデータベースエンジンと同様に、変数を複数設定できる。
(1番目、2番目・・)
・?NNN 変数を番号で設定できる。(範囲は1〜最大値)
・:AAAA 変数を「:」(コロン)と名前を設定できる。
・@AAA 「:AAA」と同様に利用できる。
例 SELECT * FROM [テーブル名] WHERE no = ? team = ?
SELECT * FROM [テーブル名] WHERE no = ?1 team = ?2
SELECT * FROM [テーブル名] WHERE no = :AA team = :BB
|
【関数名】int sqlite3_prepare_v2( sqlite3 *db, const char *zSql, int nByte,
sqlite3_stmt **ppStmt, const char **pzTail );
・機能 SQL文をコンパイルし、ステートメント・ハンドルに設定する。
・引数 *db :データベース・ハンドル
*zSql :コンパイルするSQL文
nByte :読み込むバイト数、−1でnullまで読みこむ。
**ppStmt :ステートメント・ハンドルのアドレス
**pzTail :SQL文の読み込んでいない部分のアドレス
・戻り値 SQLITE_OK (0)(OK)
0以外の場合は、エラー
|
【関数名】int sqlite3_step( sqlite3_stmt *stmt )
・機能 SQL文を1回実行する。
・引数 *dstmt :ステートメント・ハンドル
・戻り値 SQLITE_ROW (100) ・・・select
SQLITE_DONE (101)・・・insert、update、delete
以外は、エラー |
【関数名】int sqlite3_bind_int or double( sqlite3_stmt *stmt,
int num , int or doble value ) ;
int sqlite3_bind_text( sqlite3_stmt *stmt, int num ,
const char *word ,int char_num , void* );
・機能 SQL文のパラメータ(変数)に、値(integer、real、text)を設定する。
・引数 *dstmt :ステートメント・ハンドル
num :設定対象のパラメータ(変数)番号
volue :設定する値
word :設定する文字列
char_num :読み込む文字列、-1で、nullまで読み込む。
void : SQLITE_TRANSIENT
・戻り値 SQLITE_OK (0)(OK)
0以外の場合は、エラー |
【関数名】int sqlite3_reset( sqlite3_stmt *stmt )
・機能 ステートメント・ハンドルをリセットする。
・引数 *dstmt :ステートメント・ハンドル
・戻り値 SQLITE_OK (0):直前のsqlite3_step()がSQLITE_ROW(100)または SQLITE_DONE
(101)
それ以外はエラー:直前のsqlite3_step()がエラーの場合
|
【関数名】int sqlite3_finalize( sqlite3_stmt *stmt )
・機能 ステートメント・ハンドルを破棄する。
・引数 *dstmt :ステートメント・ハンドル
・戻り値 SQLITE_OK (0):直前の処理がSQLITE_ROW(100)または
SQLITE_DONE (101)、SQLITE_OK (0)の場合
それ以外はエラー:直前の処理がエラーの場合
|
【関数名】int sqlite3_column_int( sqlite3_stmt *stmt, int icol ;
double sqlite3_column_double( sqlite3_stmt *stmt, int icol) ;
const unsigned char sqlite3_column_text( sqlite3_stmt *stmt, int
icol );
・機能 指定されたcolumn(列)の値(整数、実数)、文字列を取得する。
・引数 *dstmt :ステートメント・ハンドル
icol :列番号
・戻り値 int , double , char
|
【関数名】int sqlite3_bind_parameter_count( sqlite3_stmt *stmt) ;
int sqlite3_bind_parameter_index( sqlite3_stmt *stmt,
const char *par_name ) ;
const char sqlite3_bind_parameter_name( sqlite3_stmt *stmt, int
icol );
・機能 パラメータ(変数)を扱うために使う。
・引数 *dstmt :ステートメント・ハンドル
*col_name :パラメータ名
icol :列番号
・戻り値
sqlite3_bind_parameter_count() :パラメータ(変数)の数を返す。
sqlite3_bind_parameter_index() :設定したパラメータの番号を取得する。
主に、パラメータを「:AAAA」のように名前で指定した場合に使う。
sqlite3_bind_parameter_name() :パラメータ番号を指定して、
パラメータ名(例、「:AAAA」)を取得する。
|
SQLITE、リザルトコード、エラーコード
SQLITE_OK 0 成功
SQLITE_ERROR 1 一般エラー
SQLITE_ABORT 4 コールバック・ルーチンが中止を求める。
SQLITE_BUSY 5 データベース・ファイルがロックされている。
SQLITE_LOCKED 6 テーブルがロックされている。
SQLITE_CANTOPEN 14 データベース・ファイルがオープンできない。
SQLITE_CONSTRAINT 19 制約違反で中断した。
SQLITE_MISMATCH 20 データタイプがあっていない。
SQLITE_MISUSE 21 ライブラリの使い方が正しくない。
SQLITE_ROW 100 sqlite3_step() で次のデータがある。(検索)
SQLITE_DONE 101 sqlite3_step() で操作が完了した。(挿入、更新)
|
1)挿入、更新、検索
・sqlite3_prepare_v2()関数で、ステートメント・ハンドル(*stmt)にパラメータを含めた「insert」用、「update」用、「select」用のSQL文を紐づけます。パラメータに、sqlite3_bind_*()関数で登録データを設定してデータベース・ファイル(batting_utf8.db)に挿入、更新、検索を行う。
・日本語項目は、SJIS->UTF8変換して登録します。設定には、sqlite3_bind_text文を使います。検索時、「SELECT
* FROM batting_utf8_2019 WHERE name = ?2 AND team = ?3」のように使います。。
・ソースプログラムが@、プログラムの実行結果はA(挿入)、B(更新、検索)です。
@ソース・プログラム
// -------------------------------------------------
// sqlite_27.c SQLite テストプログラム
// ・prepare,stepを使う
// ・select , insert , update 処理
// ・日本語項目はUTF8
// 2022/02/08 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}
};
// --------------- prototype --------------------
void set_batting_data( sqlite3_stmt * );
void disp_batting_data( void );
BATTING batting_data;
// --------------- 共通 -------------------------
char sql_statement[2000];
sqlite3_stmt* stmt_select; // 検索 用
sqlite3_stmt* stmt_insert; // 挿入 用
sqlite3_stmt* stmt_update; // 更新 用
sqlite3_stmt* stmt_disp; // 表示 用
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
int i ;
int rc; // 結果
sqlite3 *db;
char *db_name = "batting_utf8.db";
char *table_name = "batting_utf8_2019";
char *error_message;
// データベース定義
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 ,\
PRIMARY KEY(name, team)";
// SQLITE stmt 用の設定
char *sql_statement_select ="SELECT * FROM batting_utf8_2019
WHERE name = ?2 AND team = ?3";
char *sql_statement_insert = "INSERT INTO batting_utf8_2019
VALUES( ?1 , ?2 , ?3 , ?4 , ?5 , ?6 , ?7 , ?8 , ?9 ,?10 , ?11 , ?12 )";
char *sql_statement_update = "UPDATE batting_utf8_2019
SET at_bat =?5 , hit =?6 WHERE name = ?2 AND team = ?3";
char *sql_statement_disp = "SELECT * FROM batting_utf8_2019 ORDER BY no";
// UTF 変換用
char utf8_name[200];
char utf8_team[200];
// NKF(SJIS-UTF-8変換設定)
SetNkfOption("-w");
// データベースファイルを作成
rc = sqlite3_open_v2( db_name , &db ,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , NULL);
// データベース テーブル作成
sprintf(sql_statement, "create table %10s(%10s)", table_name, table);
rc = sqlite3_exec(db, sql_statement, NULL, NULL, &error_message );
// SQLite statement 設定( 検索 、挿入 、更新 、表示)
sqlite3_prepare_v2(db, sql_statement_select, -1, &stmt_select, NULL);
sqlite3_prepare_v2(db, sql_statement_insert, -1, &stmt_insert, NULL);
sqlite3_prepare_v2(db, sql_statement_update, -1, &stmt_update, NULL);
sqlite3_prepare_v2(db, sql_statement_disp, -1, &stmt_disp, NULL);
// 挿入
for(i=0 ; i < 30 ; i++){
// NKF(UTF-8変換)
NkfConvert( utf8_name , batting[i].name);
NkfConvert( utf8_team , batting[i].team);
sqlite3_bind_int(stmt_insert, 1, batting[i].no );
sqlite3_bind_text(stmt_insert, 2, utf8_name ,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(stmt_insert, 3, utf8_team ,-1,SQLITE_TRANSIENT);
sqlite3_bind_double(stmt_insert, 4, batting[i].batting_average );
sqlite3_bind_int(stmt_insert, 5, batting[i].at_bat );
sqlite3_bind_int(stmt_insert, 6, batting[i].hit );
sqlite3_bind_int(stmt_insert, 7, batting[i].home_run );
sqlite3_bind_int(stmt_insert, 8, batting[i].run );
sqlite3_bind_int(stmt_insert, 9, batting[i].strikeout );
sqlite3_bind_int(stmt_insert, 10, batting[i].double_play );
sqlite3_bind_double(stmt_insert, 11, batting[i].extra_base_percentage);
sqlite3_bind_double(stmt_insert, 12, batting[i].on_base_percentage);
rc = sqlite3_step(stmt_insert);
if(rc != SQLITE_DONE){
fprintf(stdout, "INSERT NG:[%d %d]\n", i+1 , rc);
return 0;
}
sqlite3_reset(stmt_insert);
}
fprintf(stdout,"順位 選手 球団 打率 打数 安打
本塁打 打点 三振 併殺打 長打率 出塁率\n");
// UPDATE "鈴木 誠也" ,"(広)" があれば、 打数と安打数を0に更新 。
NkfConvert( utf8_name , "鈴木 誠也");
NkfConvert( utf8_team , "(広)");
sqlite3_bind_text(stmt_select, 2, utf8_name ,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(stmt_select, 3, utf8_team ,-1,SQLITE_TRANSIENT);
rc = sqlite3_step(stmt_select);
fprintf(stdout , "== 変更前==\n");
set_batting_data( stmt_select );
disp_batting_data();
fprintf(stdout , "== 変更後==\n");
if( rc == SQLITE_ROW){
sqlite3_bind_int(stmt_update, 5, 0 );
sqlite3_bind_int(stmt_update, 6, 0 );
sqlite3_bind_text(stmt_update, 2, utf8_name ,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(stmt_update, 3, utf8_team ,-1,SQLITE_TRANSIENT);
rc = sqlite3_step(stmt_update);
if(rc != SQLITE_DONE){
fprintf(stdout, "UPDATE NG:[%s]\n", sqlite3_errmsg(db));
return 0;
}
sqlite3_reset(stmt_update);
}
sqlite3_reset(stmt_select);
// 1件の表示・・・・変更後
rc = sqlite3_step(stmt_disp);
if(rc == SQLITE_ROW){
set_batting_data(stmt_disp);
disp_batting_data();
}
sqlite3_reset(stmt_disp);
rc = sqlite3_finalize(stmt_select);
rc = sqlite3_finalize(stmt_insert);
rc = sqlite3_finalize(stmt_update);
rc = sqlite3_finalize(stmt_disp);
rc = sqlite3_close(db);
return 0;
}
// =========================================================================
// Name : void set_batting_data( sqlite3_stmt* )
// Usage : 検索データを構造体にセットする。
// Parameter: なし
// Return : なし
// =========================================================================
void set_batting_data( sqlite3_stmt* stmt )
{
int i = 0;
// UTF8 、sjis 変換用
char utf8_name[200];
char utf8_team[200];
char sjis_name[200];
char sjis_team[200];
SetNkfOption("-s");
batting_data.no = sqlite3_column_int(stmt, i++);
strcpy(utf8_name , (char*) sqlite3_column_text(stmt, i++));
strcpy(utf8_team , (char*) sqlite3_column_text(stmt, i++));
NkfConvert( sjis_name , utf8_name);
NkfConvert( sjis_team , utf8_team);
strcpy(batting_data.name , sjis_name );
strcpy(batting_data.team , sjis_team );
batting_data.batting_average = sqlite3_column_double(stmt, i++);
batting_data.at_bat = sqlite3_column_int(stmt, i++);
batting_data.hit = sqlite3_column_int(stmt, i++);
batting_data.home_run = sqlite3_column_int(stmt, i++);
batting_data.run = sqlite3_column_int(stmt, i++);
batting_data.strikeout = sqlite3_column_int(stmt, i++);
batting_data.double_play = sqlite3_column_int(stmt, i++);
batting_data.extra_base_percentage = sqlite3_column_double(stmt, i++);
batting_data.on_base_percentage = sqlite3_column_double(stmt, i++);
return;
}
// =========================================================================
// Name : void disp_batting_data(void)
// Usage : データを表示する。
// Parameter: なし
// Return : なし
// =========================================================================
void disp_batting_data( void )
{
fprintf(stdout,"%2ld %-12s %-6s %1.3lf %3ld
%3ld %3ld %3ld %3ld %3ld %1.3lf %1.3lf\n",
batting_data.no , batting_data.name , batting_data.team ,
batting_data.batting_average , batting_data.at_bat,
batting_data.hit , batting_data.home_run , batting_data.run,
batting_data.strikeout , batting_data.double_play ,
batting_data.extra_base_percentage ,
batting_data.on_base_percentage);
return;
}
A実行結果

2)ROWIDの利用
ROWIDは、SQLiteの各行を識別するために設定されます。(ROWIDを設けないDBも作成できます)ROWIDは「OID」、「_ROWID_」も同じものを指し示しています。
「挿入、更新、検索」と同じ処理を行うソースプログラムが@、プログラムの実行結果はAです。
select文では、「select ROWID, *」で、ROWIDを含めます。Update文では、「update ・・・ where ROWID
= ?」のように、行を指定して更新します。
Bソースプログラム(ROWID)
// -------------------------------------------------
// sqlite_28.c SQLite テストプログラム
// ・rowid を使う。
// ・prepare,stepを使う
// ・select , insert , update 処理
// ・日本語項目はUTF8
// 2022/02/08 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}
};
// --------------- prototype --------------------
void set_batting_data( sqlite3_stmt * );
void disp_batting_data( void );
BATTING batting_data;
// --------------- 共通 -------------------------
char sql_statement[2000];
sqlite3_stmt* stmt_select; // 検索 用
sqlite3_stmt* stmt_insert; // 挿入 用
sqlite3_stmt* stmt_update; // 更新 用
sqlite3_stmt* stmt_disp; // 表示 用
long rowid; // ROWID
// =========================================================================
// Name : int main(void)
// Usage : メイン関数
// Parameter: なし
// Return :
// =========================================================================
int main(void)
{
int i ;
int rc; // 結果
sqlite3 *db;
char *db_name = "batting_utf8_2.db";
char *table_name = "batting_utf8_2019";
char *error_message;
// データベース定義
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 ,\
PRIMARY KEY(name, team)";
// SQLITE stmt 用の設定
char *sql_statement_select ="SELECT ROWID , * FROM batting_utf8_2019
WHERE name like ?2 AND team like ?3";
char *sql_statement_insert = "INSERT INTO batting_utf8_2019
VALUES( ?1 , ?2 , ?3 , ?4 , ?5 , ?6 , ?7 , ?8 , ?9 ,?10 , ?11 , ?12 )";
char *sql_statement_update = "UPDATE batting_utf8_2019
SET at_bat =?5 , hit =?6 WHERE ROWID = :rowid";
char *sql_statement_disp ="SELECT ROWID , * FROM batting_utf8_2019 ORDER BY no";
// UTF 変換用
char utf8_name[200];
char utf8_team[200];
// NKF(SJIS-UTF-8変換設定)
SetNkfOption("-w");
// データベースファイルを作成
rc = sqlite3_open_v2( db_name , &db ,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , NULL);
// データベース テーブル作成
sprintf(sql_statement, "create table %10s(%10s)", table_name, table);
rc = sqlite3_exec(db, sql_statement, NULL, NULL, &error_message );
// SQLite statement 設定( 検索 、挿入 、更新 、表示)
sqlite3_prepare_v2(db, sql_statement_select, -1, &stmt_select, NULL);
sqlite3_prepare_v2(db, sql_statement_insert, -1, &stmt_insert, NULL);
sqlite3_prepare_v2(db, sql_statement_update, -1, &stmt_update, NULL);
sqlite3_prepare_v2(db, sql_statement_disp, -1, &stmt_disp, NULL);
// 挿入
for(i=0 ; i < 30 ; i++){
// NKF(UTF-8変換)
NkfConvert( utf8_name , batting[i].name);
NkfConvert( utf8_team , batting[i].team);
sqlite3_bind_int(stmt_insert, 1, batting[i].no );
sqlite3_bind_text(stmt_insert, 2, utf8_name ,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(stmt_insert, 3, utf8_team ,-1,SQLITE_TRANSIENT);
sqlite3_bind_double(stmt_insert, 4, batting[i].batting_average );
sqlite3_bind_int(stmt_insert, 5, batting[i].at_bat );
sqlite3_bind_int(stmt_insert, 6, batting[i].hit );
sqlite3_bind_int(stmt_insert, 7, batting[i].home_run );
sqlite3_bind_int(stmt_insert, 8, batting[i].run );
sqlite3_bind_int(stmt_insert, 9, batting[i].strikeout );
sqlite3_bind_int(stmt_insert, 10, batting[i].double_play );
sqlite3_bind_double(stmt_insert, 11, batting[i].extra_base_percentage);
sqlite3_bind_double(stmt_insert, 12, batting[i].on_base_percentage);
rc = sqlite3_step(stmt_insert);
if(rc != SQLITE_DONE){
fprintf(stdout, "INSERT NG:[%d %d]\n", i+1 , rc);
return 0;
}
sqlite3_reset(stmt_insert);
}
fprintf(stdout,"ROWID 順位 選手 球団 打率 打数
安打 本塁打 打点 三振 併殺打 長打率 出塁率\n");
// UPDATE "鈴木 誠也" ,"(広)" があれば、 打数と安打数を0に更新 。
NkfConvert( utf8_name , "鈴木 誠也");
NkfConvert( utf8_team , "(広)");
sqlite3_bind_text(stmt_select, 2, utf8_name ,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(stmt_select, 3, utf8_team ,-1,SQLITE_TRANSIENT);
rc = sqlite3_step(stmt_select);
fprintf(stdout , "== 変更前==\n");
set_batting_data( stmt_select );
disp_batting_data();
fprintf(stdout , "== 変更後==\n");
if( rc == SQLITE_ROW){
sqlite3_bind_int(stmt_update, 5, 0 );
sqlite3_bind_int(stmt_update, 6, 0 );
sqlite3_bind_int(stmt_update,
sqlite3_bind_parameter_index(stmt_update , ":rowid"), rowid );
rc = sqlite3_step(stmt_update);
if(rc != SQLITE_DONE){
fprintf(stdout, "UPDATE NG:[%s]\n", sqlite3_errmsg(db));
return 0;
}
sqlite3_reset(stmt_update);
}
sqlite3_reset(stmt_select);
// 1件の表示・・・・変更後
rc = sqlite3_step(stmt_disp);
if(rc == SQLITE_ROW){
set_batting_data(stmt_disp);
disp_batting_data();
}
sqlite3_reset(stmt_disp);
rc = sqlite3_finalize(stmt_select);
rc = sqlite3_finalize(stmt_insert);
rc = sqlite3_finalize(stmt_update);
rc = sqlite3_finalize(stmt_disp);
rc = sqlite3_close(db);
return 0;
}
// =========================================================================
// Name : void set_batting_data( sqlite3_stmt* )
// Usage : 検索データを構造体にセットする。
// Parameter: なし
// Return : なし
// =========================================================================
void set_batting_data( sqlite3_stmt* stmt )
{
int i = 0;
// UTF8 、sjis 変換用
char utf8_name[200];
char utf8_team[200];
char sjis_name[200];
char sjis_team[200];
// NKF(SJIS-UTF-8変換設定)
SetNkfOption("-s");
rowid = sqlite3_column_int(stmt, i++);
batting_data.no = sqlite3_column_int(stmt, i++);
// NKF(SJIS変換)
strcpy(utf8_name , (char*) sqlite3_column_text(stmt, i++));
strcpy(utf8_team , (char*) sqlite3_column_text(stmt, i++));
NkfConvert( sjis_name , utf8_name);
NkfConvert( sjis_team , utf8_team);
strcpy(batting_data.name , sjis_name );
strcpy(batting_data.team , sjis_team );
batting_data.batting_average = sqlite3_column_double(stmt, i++);
batting_data.at_bat = sqlite3_column_int(stmt, i++);
batting_data.hit = sqlite3_column_int(stmt, i++);
batting_data.home_run = sqlite3_column_int(stmt, i++);
batting_data.run = sqlite3_column_int(stmt, i++);
batting_data.strikeout = sqlite3_column_int(stmt, i++);
batting_data.double_play = sqlite3_column_int(stmt, i++);
batting_data.extra_base_percentage = sqlite3_column_double(stmt, i++);
batting_data.on_base_percentage = sqlite3_column_double(stmt, i++);
return;
}
// =========================================================================
// Name : void disp_batting_data(void)
// Usage : データを表示する。
// Parameter: なし
// Return : なし
// =========================================================================
void disp_batting_data( void )
{
fprintf(stdout,"%2ld %2ld %-12s %-6s %1.3lf %3ld %3ld
%3ld %3ld %3ld %3ld %1.3lf %1.3lf\n",
rowid ,
batting_data.no , batting_data.name , batting_data.team ,
batting_data.batting_average , batting_data.at_bat,
batting_data.hit , batting_data.home_run , batting_data.run,
batting_data.strikeout , batting_data.double_play ,
batting_data.extra_base_percentage , batting_data.on_base_percentage);
return;
}
C実行結果


|