SQLite3のバインディング関数ファミリーの使い方とその注意点解説
2022-01-09 23:39:08
前書き
この記事で紹介するコードは、実際にSqlite3のパラメータ化機構を使って、データの挿入や更新操作を行う方法です。
以下のコードでは、挿入されるものが必ずそうでなければならないという問題があります。
INSERT INTO "work" VALUES('hafnium','hafnium hafnium hafnium',NULL,NULL,NULL,NULL,NULL,'hafnium hafnium hafnium',NULL,NULL,110.0,1.0,108.9,NULL,NULL,'hafnium hafnium hafnium',NULL,NULL, NULL,'hafnium hafnium hafnium hafnium',NULL,NULL,NULL);
問題のあるコードを見てください。
sqlite3_stmt *stmt;
CString sql = "insert into work values (? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,?) ";
int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL);
if(rc ! = SQLITE_OK)
{
MessageBox("sqlite3_prepare_v2 Failed!");
return;
}
count = 0;
p_wnd = PrevWnd;
while(count++ < ID_TOTALCOUNT)
{
CString DbStr;
p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE);
if(p_wnd == NULL)
{
return;
}
p_wnd->GetWindowText(DbStr);
do
{
if(!DbStr.GetLength())
{
rc = sqlite3_bind_null(stmt, count);
break;
}
// Date related
if( count == ID_CHUDANRIQI ||
count == ID_CHUFARIQI ||
count == ID_HUANKUANRIQI ||
count == ID_HUOLIRIQI)
{
CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd;
CString time = DateTimeToString(*TimeCtl);
rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC);
break;
}
else
{
// Money related processing real type
if( count == ID_BAOXIANJINE ||
count == ID_YONGJINBILV ||
count == ID_JINGBAOFEI ||
count == ID_HUANKUANJINE ||
count == ID_LIRUNBILV || count == ID_LIRUNBILV
count == ID_LIRUNJINE)
{
double tMoney = 0.0;
int rtn = sscanf_s(DbStr.GetString(), "%lf", &tMoney);
ASSERT(rtn == 1);
rc = sqlite3_bind_double(stmt, count, tMoney);
}
else
{
char *str = (char *)DbStr.GetString();
int c = strlen(str);
int c1 = DbStr.GetLength();
rc = sqlite3_bind_text(stmt, count, DbStr.GetString(), -1/*DbStr.GetLength()*/, SQLITE_STATIC);
}
}
}while(0);
if(rc ! = SQLITE_OK)
{
CString ErrStr = sqlite3_errstr(rc);
MessageBox(ErrStr);
return;
}
}
rc = sqlite3_step(stmt);
if(rc ! = SQLITE_DONE)
{
if(rc == SQLITE_ERROR)
{
CString DbErr;
DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db));
MessageBox(DbErr);
}
else
{
MessageBox("sqlite3_step Failed!");
}
}
sqlite3_finalize(stmt);
なぜ?
なぜなら、sqlite3_bind_textバインディングのテキストは、事前に行われる必要があるからです。
rc = sqlite3_step(stmt);
が一律にコミットされます。
rc = sqlite3_step(stmt);
は、コードが送信される頃にはとっくに消えています。だから、コードが乱雑になるのは当たり前なんです。
以下を修正します。
sqlite3_stmt *stmt;
CString sql = "insert into work values (? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,?) ";
int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL);
if(rc ! = SQLITE_OK)
{
MessageBox("sqlite3_prepare_v2 Failed!");
return;
}
count = 0;
p_wnd = PrevWnd;
CString DbStr[ID_TOTALCOUNT + 1];
while(count++ < ID_TOTALCOUNT)
{
DbStr[count].Empty();
p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE);
if(p_wnd == NULL)
{
return;
}
p_wnd->GetWindowText(DbStr[count]);
do
{
if(!DbStr[count].GetLength())
{
rc = sqlite3_bind_null(stmt, count);
break;
}
// Date related
if( count == ID_CHUDANRIQI ||
count == ID_CHUFARIQI ||
count == ID_HUANKUANRIQI ||
count == ID_HUOLIRIQI)
{
CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd;
CString time = DateTimeToString(*TimeCtl);
DbStr[count] = time;
rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC);
}
else
{
// Money related processing real type
if( count == ID_BAOXIANJINE ||
count == ID_YONGJINBILV ||
count == ID_JINGBAOFEI ||
count == ID_HUANKUANJINE ||
count == ID_LIRUNBILV || count == ID_LIRUNBILV
count == ID_LIRUNJINE)
{
double tMoney = 0.0;
int rtn = sscanf_s(DbStr[count].GetString(), "%lf", &tMoney);
ASSERT(rtn == 1);
rc = sqlite3_bind_double(stmt, count, tMoney);
}
else
{
rc = sqlite3_bind_text(stmt, count, DbStr[count].GetString(), DbStr[count].GetLength(), SQLITE_STATIC);
}
}
}while(0);
if(rc ! = SQLITE_OK)
{
CString ErrStr = sqlite3_errstr(rc);
MessageBox(ErrStr);
return;
}
}
rc = sqlite3_step(stmt);
if(rc ! = SQLITE_DONE)
{
if(rc == SQLITE_ERROR)
{
CString DbErr;
DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db));
MessageBox(DbErr);
}
else
{
MessageBox("sqlite3_step Failed!");
}
}
sqlite3_finalize(stmt);
データベースを作成するためのSQL構文を添付します。
sqlite> .dump work
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE work (baodanhao text unique primary key , chudanriqi text,qudao text,lianxiren text,xiaoshou text,beibaorenxingming text,chufar
iqi text,baooxianpinpai text,baooxianjihua text,baooxianjine real,yongjinbilv real,jingbaofei real,huankuanfangshi text,haikuanjine real, huanku
anriqi text,shifouquane text,lirunbilv real,lirunjine real,huoliriqi text,fapiaojisong text,shifubaoxiangongsi text,beizhu text);
概要
以上、この記事の内容はすべてです、私はこの記事の内容はあなたの勉強や仕事にいくつかの助けをもたらすことができることを願って、あなたが質問を持っている場合は、交換するメッセージを残すことができます、スクリプトハウスへのあなたのサポートをありがとうございました。
関連
-
よく使われるsQliteステートメントとsQliteデベロッパーの使用・登録について
-
ESCAPE を使用して SQL でエスケープを定義する
-
SQLiteパフォーマンス最適化例共有
-
SQLiteチュートリアル(V): データベースとトランザクション
-
SQLiteの文字列比較における大文字小文字の問題の解決法
-
SQLiteデータベースのインストールと基本操作ガイド
-
SQLite3 コマンドライン操作ガイド
-
SQLite3 用に ANSI から UTF8 への交換関数を提供する。
-
SQLiteチュートリアル(I)。SQLiteデータベース入門
-
SQLiteチュートリアル(V): インデックス作成とデータ解析・クリーニング
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python の sqlalchemy テーブル作成例 詳細
-
SQLiteの便利なコマンドのまとめ
-
SQLite3の自己追加型主キーに関連する知識のまとめ
-
SQLiteのエラーコードのソート
-
SQLiteデータベースの共通文とMACでのSQLite用可視化ツール「MeasSQLlite」の利用について
-
Sqliteデータベースの最大挿入データ数は500個です。
-
SQLiteで自動番号付けされたカラムをリセットする方法
-
SQLiteチュートリアル(VIII)。コマンドラインツールの紹介
-
SQLiteチュートリアル(IV)。組み込み関数
-
SQLiteチュートリアル(3)。データテーブルとビューの紹介