○ODBC カーソルでデータの更新

Select文により取得した値を更新します


#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <tchar.h>
#include <sql.h>
#include <sqlext.h>

//-----------------------------------------
//ODBC 接続
//-----------------------------------------
bool Connect(TCHAR*server,TCHAR*uid,TCHAR*pwd,HENV*henv, HDBC*hdbc,HSTMT*hstmt){
	SQLAllocEnv(henv);//環境ハンドルの割り当て
	SQLAllocConnect(*henv, hdbc);//接続ハンドルの割り当て
	//データ・ソースへの接続
	RETCODE rc = SQLConnect(*hdbc,(SQLTCHAR*)server,SQL_NTS,(SQLTCHAR*)uid,SQL_NTS,(SQLTCHAR*)pwd, SQL_NTS);
	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
		return false;
	}
	SQLAllocStmt(*hdbc, hstmt);//ステートメント・ハンドルの割り当て
	return true;
}

//-----------------------------------------
//ODBC 切断
//-----------------------------------------
void Close(HENV*henv, HDBC*hdbc,HSTMT*hstmt){
	SQLFreeStmt(hstmt, SQL_DROP);//ステートメント・ハンドルの解放
	SQLDisconnect(*hdbc);//データ・ソースからの切断
	SQLFreeConnect(*hdbc);// 接続ハンドルの解放
	SQLFreeEnv(*henv);//環境ハンドルの解放
}

//-----------------------------------------
//ODBC SQLの実行
//-----------------------------------------
bool Execute(HENV*henv, HDBC*hdbc, HSTMT*hstmt,TCHAR*SQLStr){
	//ステートメントの直接の実行
	RETCODE rc = SQLExecDirect(*hstmt,(SQLTCHAR*)SQLStr, SQL_NTS);
	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)  {
	   return false;
	}
	return true;
}

int main() {

	HENV   henv;//ODBC 環境ハンドル
	HDBC   hdbc;//ODBC 接続ハンドル
	HSTMT  hstmt;//ODBC ステートメント・ハンドル


	//========================================================
	//接続 ODBCデータソース名 ユーザー名 パスワード
	if(!Connect(TEXT("test"),TEXT("sa"),TEXT(""),&henv,&hdbc,&hstmt)){
		printf("接続エラー\n");
		return 1;
	}

	//アプリケーション変数への列のバインド(変数に関連付け)
	DWORD  intval;
	double realval;
	static TCHAR str[32768];

	while(1){
		//カーソルの種類、キーセット ドリブン
		if(SQL_SUCCESS!=SQLSetStmtAttr(hstmt,SQL_ATTR_CURSOR_TYPE ,(SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN,0)){
			printf("エラー\n");
			return 1;
		}

		//カーソル同時実行、ロックの種類を行にする
		//SQL_CONCUR_READ_ONLY
		//SQL_CONCUR_ROWVER
		//SQL_CONCUR_VALUES
		//SQL_CONCUR_LOCK
		if(SQL_SUCCESS!=SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY,(SQLPOINTER)SQL_CONCUR_LOCK,0)){
			printf("エラー\n");
			return 1;
		}

		if(SQL_SUCCESS!=SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE,(SQLPOINTER)1,0)){
			printf("エラー\n");
			return 1;
		}

		//結果を返すSQL文の実行
		Execute(&henv,&hdbc,&hstmt,TEXT("SELECT * FROM table2"));


		//SQLBindCol(hstmt, 1, SQL_C_SLONG, &intval, (SDWORD)sizeof(intval), NULL);
		//値を文字として取得しても動作する
		SQLBindCol(hstmt, 1, SQL_C_TCHAR, &str, (SDWORD)sizeof(str),NULL);

		SQLBindCol(hstmt, 2, SQL_C_DOUBLE , &realval, (SDWORD)sizeof(realval), NULL);

		while(1){
			//MDAC2.8で同一行をカーソルでSQLFetchした場合、デットロックが発生し、
			//タイムアウト後のエラーが検出できない問題があるため注意
			RETCODE rc = SQLFetch(hstmt);

			if( rc == SQL_NO_DATA_FOUND )
				break;
			if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO ) {
				printf("ERR1\n");
				break;
			}

			//読み取った値を更新する--------------
			//intval++;
			int i=_ttoi(str);//値を文字として取得
			realval++;
			_stprintf(str,TEXT("%d"),++i);//値を文字として更新
			//------------------------------------
			//結果セット列にバインドされているプログラム変数に格納されている値で、カーソルの現在行を更新
			if(SQL_SUCCESS!=SQLSetPos(hstmt, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE)){
				printf("ERR2\n");
				//break;
			}
		}

		SQLFreeStmt(hstmt, SQL_DROP);//ステートメント・ハンドルの解放
		SQLAllocStmt(hdbc, &hstmt);//ステートメント・ハンドルの再割り当て
		//eキーが押されるまで繰り返す
		if(_kbhit()) if('e'==_getch()) break;

	}
	//切断
	Close(&henv,&hdbc,&hstmt);
	//========================================================

	printf("END\n");
	getchar();
	return 0;
}




▲トップページ > Windows と C++