開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 コンソール アプリケーション
プロジェクト名 odbctest
アプリケーションの種類 コンソール アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

createdb.cpp
#include <fcntl.h>	// _O_WTEXT
#include <io.h>		// _setmode
#include <stdio.h>	// _fileno
#include <Windows.h>
#include <sqlext.h>
#include <odbcinst.h>
#include <tchar.h>
 
#define DRIVER_MAIN _T("Microsoft Access Driver (*.mdb)")
#define DRIVER_SUB _T("Microsoft Text Driver (*.txt; *.csv)")
#define DB_DIR _T("C:\\projects\\vc++\\odbctest\\")
#define DATABASE DB_DIR _T("odbctest.mdb")
#define TABLE _T("09TOCHIG.CSV")
 
// 関数プロトタイプ宣言
int create_db(void);
int connect_db(SQLHENV henv, SQLHDBC *phdbc, SQLTCHAR *ptcConnStr);
int create_table(SQLHDBC hdbc);
int insert_record(SQLHENV henv, SQLHDBC hdbcMain);
int select_table(SQLHDBC hdbc);
 
//==============================================================================
int main()
{
	SQLHENV henv;	// 環境ハンドル
	SQLHDBC hdbc;	// 接続ハンドル
	SQLRETURN rc;	// retcode
 
	// BOMなしUTF-16LE
	_setmode(_fileno(stdout), _O_WTEXT);
	_setmode(_fileno(stderr), _O_WTEXT);
 
	// データベースの作成
	if (create_db()) return 1;
 
	// 環境ハンドルの確保
	rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
	rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
 
	// データベースへの接続
	if (connect_db(henv, &hdbc, _T("driver={") DRIVER_MAIN _T("}; dbq=") DATABASE))
		return 1;
 
	// テーブルの作成
	if (create_table(hdbc)) return 1;
 
	// レコードの追加
	if (insert_record(henv, hdbc)) return 1;
 
	// 検索
	select_table(hdbc);
 
	// 終了処理
	SQLDisconnect(hdbc);
	SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
	SQLFreeHandle(SQL_HANDLE_ENV, henv);
	return 0;
}
 
//------------------------------------------------------------------------------
int create_db(void)
{
	_TCHAR tc;
	BOOL b;
 
	if (_taccess(DATABASE, 0) == 0) {
		_tprintf(_T("remove %s (y/n)"), DATABASE);
		_tscanf_s(_T("%c"), &tc);
		if (tc != _T('y')) return -1;
		_tremove(DATABASE);
	}
	b = SQLConfigDataSource(NULL, ODBC_ADD_DSN, DRIVER_MAIN,
		_T("create_db=") DATABASE _T("\0"));
	if (b == FALSE) {
		_ftprintf(stderr, _T("データベースの作成に失敗しました\n"));
		return -1;
	}
	return 0;
}
 
//------------------------------------------------------------------------------
int connect_db(SQLHENV henv, SQLHDBC *phdbc, SQLTCHAR *ptcConnStr)
{
	SQLRETURN rc;	// retcode
 
	rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, phdbc);
	rc = SQLDriverConnect(*phdbc, NULL, ptcConnStr, SQL_NTS,
		NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
	if (!SQL_SUCCEEDED(rc)) {
		_ftprintf(stderr, _T("データベースへの接続に失敗しました\n"));
		return -1;
	}
	return 0;
}
 
//------------------------------------------------------------------------------
int create_table(SQLHDBC hdbc)
{
	SQLHSTMT hstmt;	// 命令ハンドル
	SQLRETURN rc;	// retcode
 
	rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
	rc = SQLExecDirect(hstmt, (SQLTCHAR *)
		_T("create table 郵便番号データ (")
		_T("全国地方公共団体コード text(5),")
		_T("旧郵便番号 text(5),")
		_T("郵便番号 text(7),")
		_T("都道府県名カナ text,")
		_T("市区町村名カナ text,")
		_T("町域名カナ text(76),")
		_T("都道府県名 text,")
		_T("市区町村名 text,")
		_T("町域名 text(38),")
		_T("一町域が二以上の郵便番号で表される場合の表示 byte,")
		_T("小字毎に番地が起番されている町域の表示 byte,")
		_T("丁目を有する町域の場合の表示 byte,")
		_T("一つの郵便番号で二以上の町域を表す場合の表示 byte,")
		_T("更新の表示 byte,")
		_T("変更理由 byte)")
		, SQL_NTS);
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	if (!SQL_SUCCEEDED(rc)) {
		_ftprintf(stderr, _T("テーブルの作成に失敗しました\n"));
		return -1;
	}
	return 0;
}
 
//------------------------------------------------------------------------------
int insert_record(SQLHENV henv, SQLHDBC hdbcMain)
{
	SQLHDBC hdbcSub;	// 接続ハンドル
	SQLHSTMT hstmtMain;	// 命令ハンドル
	SQLHSTMT hstmtSub;	// 命令ハンドル
	SQLRETURN rc;		// retcode
	SQLSMALLINT col;
	SQLSMALLINT i;
	SQLSMALLINT datatype[15];
	SQLLEN len;
	_TCHAR stmttext[256];
	_TCHAR buf[80];
	_TCHAR tmp[80];
 
	// サブDBへの接続
	if (connect_db(henv, &hdbcSub, _T("driver={") DRIVER_SUB _T("}; dbq=") DB_DIR))
		return -1;
 
	// 検索
	rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbcSub, &hstmtSub);
	rc = SQLExecDirect(hstmtSub, (SQLTCHAR *) _T("select * from ") TABLE, SQL_NTS);
	if (!SQL_SUCCEEDED(rc)) {
		return -1;
	}
 
	// データ型の取得
	rc = SQLNumResultCols(hstmtSub, &col);
	for (i = 0; i < col; i++) {
		rc = SQLDescribeCol(hstmtSub, i+1, buf, _countof(buf), NULL,
			&datatype[i], NULL, NULL, NULL);
		// Text 12 SQL_VARCHAR
		// Byte -6 SQL_TINYINT
	}
 
	// サブDBからメインDBへの転送ループ
	rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbcMain, &hstmtMain);
	while (1) {
		// サブDBから1行読み込み命令文を作る
		rc = SQLFetch(hstmtSub);
		if (rc == SQL_NO_DATA) break;
		if (rc == SQL_ERROR) break;
		_tcscpy_s(stmttext, _T("insert into 郵便番号データ values ("));
		for (i = 0; i < col; ) {
			SQLGetData(hstmtSub, i+1, SQL_C_TCHAR, buf, _countof(buf), &len);
			if (len == SQL_NULL_DATA) {
				_tcscat_s(stmttext, _T("null"));
			} else {
				switch (datatype[i]) {
				case SQL_VARCHAR:
					_stprintf_s(tmp, _T("'%s'"), buf);
					_tcscat_s(stmttext, tmp);
					break;
				default:
					_tcscat_s(stmttext, buf);
				}
			}
			_tcscat_s(stmttext, (++i == col) ? _T(")") : _T(","));
		}
 
		// メインDBへのレコードの追加
		rc = SQLExecDirect(hstmtMain, stmttext, SQL_NTS);
		if (!SQL_SUCCEEDED(rc)) {
			_ftprintf(stderr, _T("レコードの追加に失敗しました\n"));
			return -1;
		}
	}
	SQLFreeHandle(SQL_HANDLE_STMT, hstmtMain);
	SQLFreeHandle(SQL_HANDLE_STMT, hstmtSub);
 
	// トランザクション終了
	rc = SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
 
	// サブDBへの接続を解除
	SQLDisconnect(hdbcSub);
	SQLFreeHandle(SQL_HANDLE_DBC, hdbcSub);
	return 0;
}
 
//------------------------------------------------------------------------------
int select_table(SQLHDBC hdbc)
{
	SQLHSTMT hstmt;	// 命令ハンドル
	SQLRETURN rc;	// retcode
	SQLSMALLINT col;
	SQLSMALLINT i;
	SQLTCHAR buf[256];
	SQLLEN len;
	int rec;
 
	rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
	rc = SQLExecDirect(hstmt, (SQLTCHAR *)_T("select * from 郵便番号データ"), SQL_NTS);
	rc = SQLNumResultCols(hstmt, &col);
	for (rec = 0; ; rec++) {
		rc = SQLFetch(hstmt);
		if (rc == SQL_NO_DATA) break;
		if (rc == SQL_ERROR) break;
		for (i = 1; i <= col; i++) {
			rc = SQLGetData(hstmt, i, SQL_C_TCHAR, buf, _countof(buf), &len);
			if (len == SQL_NULL_DATA) buf[0] = _T('\0');
			_tprintf(_T("%s%c"), buf, (i == col) ? _T('\n') : _T(','));
		}
	}
	_tprintf(_T("レコード数:%d\n"), rec);
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	return 0;
}
 
#if 0
//------------------------------------------------------------------------------
int insert_record(SQLHENV henv, SQLHDBC hdbc)
{
	SQLHSTMT hstmt;	// 命令ハンドル
	SQLRETURN rc;	// retcode
 
	rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
	rc = SQLExecDirect(hstmt, (SQLTCHAR *)
		_T("insert into 郵便番号データ(郵便番号,町域名) values ")
		_T("('9071801','沖縄県八重山郡与那国町与那国')")
		, SQL_NTS);
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	if (!SQL_SUCCEEDED(rc)) {
		_ftprintf(stderr, _T("レコードの追加に失敗しました\n"));
		return -1;
	}
	rc = SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
	return 0;
}
#endif
 
最終更新:2012年09月02日 20:04