SQLiteをC++から呼び出す(2:Insert)

今回は作成したTEST_TABLEにレコードをInsertしてみる。Insertする文字列をダイアログで取得した上で、Insertを実行する。MFCでのサンプルは下記のようになる。

void CMainFrame::OnInsert()
{
	//インサートするデータを入力するダイアログ
	CInsertDlg dlg ;

	CString strID ;
	CString strName ;
	CString strComment ;

	strID.Empty() ;
	strName.Empty() ;
	strComment.Empty() ;
	
	if( dlg.DoModal() == IDOK )
	{
		strID = dlg.m_strID ;
		strName = dlg.m_strName ;
		strComment = dlg.m_strComment ;
	}
	//ダイアログ終わり

	sqlite3* db;
	int err;
	_TCHAR* db_name = _T("c:\\SQLiteDB\\testDB.db");

	// データベースを開く
	err = sqlite3_open16(db_name, &db);

	if (err != SQLITE_OK)
	{
		AfxMessageBox( _T("openErr") ) ;
		return ;
	}

	CString strSQL ;
	CStringA strSQL_A ;

	const int bind_DISP_ID = 1;
	const int bind_NAME = 2;
	const int bind_COMMENT = 3;
	const int bind_REGIST_TIME = 4;
	const int bind_UPDATE_TIME = 5;

	// prepared ステートメントを用意する
	sqlite3_stmt* insert_sql;
	strSQL = _T("INSERT INTO TEST_TABLE(") ;
	strSQL +=  _T("DISP_ID, NAME, COMMENT, REGIST_TIME, UPDATE_TIME) ") ;
	strSQL +=  _T("VALUES(?,?,?,?,?);");
	err = sqlite3_prepare16(db, strSQL, strSQL.GetLength()*2, &insert_sql, NULL);
	//↑ここでエラーの場合、SQL文がおかしい

	//トランザクション開始
	sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);

	//現在時刻の文字列を得る
	SYSTEMTIME st ;
	::GetLocalTime(&st);	
	CString strNow ;
	strNow.Format(_T("%4d-%02d-%02d %02d:%02d:%02d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond ) ;

	//インサート
	err = sqlite3_reset(insert_sql);

	err = sqlite3_bind_text16(insert_sql, bind_DISP_ID, strID, strID.GetLength()*sizeof(_TCHAR), SQLITE_STATIC );
	err = sqlite3_bind_text16(insert_sql, bind_NAME, strName, strName.GetLength()*sizeof(_TCHAR), SQLITE_STATIC );
	err = sqlite3_bind_text16(insert_sql, bind_COMMENT, strComment, strComment.GetLength()*sizeof(_TCHAR), SQLITE_STATIC );
	err = sqlite3_bind_text16(insert_sql, bind_REGIST_TIME, strNow, strNow.GetLength()*sizeof(_TCHAR), SQLITE_STATIC );
	err = sqlite3_bind_text16(insert_sql, bind_UPDATE_TIME, strNow, strNow.GetLength()*sizeof(_TCHAR), SQLITE_STATIC );

	err = sqlite3_step(insert_sql);
	if( err != SQLITE_DONE )		//stepを実行した場合、SQLITE_DONEなら正解!
		AfxMessageBox(_T("stepでエラー")) ;

	// コミット
	sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);

	// プリペアしたものを破棄する
	sqlite3_finalize(insert_sql);

	sqlite3_close(db);
}

sqlite_exec」でもInsertを実行できるようなのだが、UNICODEで必要な「sqlite3_exec16」というメソッドが公式ではサポートされていない。理由は「sqlite3_exec」自体をレガシー扱いとするためらしい
。よって、UNICODE文字列を扱う場合、「sqlite3_exec」でINSERTせずに、

  • sqlite3_prepare16
  • sqlite3_reset
  • sqlite3_bind_***
  • sqlite3_step

という手順でやるしかないようだ。

Insertした結果をPupSQLiteで見てみると下図のようになる。

1行目が456しかないのは、気にしないでください。
(つづく)