「MFCとデータベース - CRUDの実行」の版間の差分
ナビゲーションに移動
検索に移動
表. CDBVariantのメンバ
表. m_dwType共用体メンバ
編集の要約なし |
(→注意点) |
||
106行目: | 106行目: | ||
== 注意点 == | == 注意点 == | ||
SQL Server等でSELECT文を発行すると、datetime型カラム等が表示できない場合がある。<br> | |||
そのため、GetFieldValueメソッドの引数にCDBVariantを使用する。<br> | |||
<br> | |||
<center> | <center>表. CDBVariantのメンバ</center> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
137行目: | 137行目: | ||
</center> | </center> | ||
<br> | <br> | ||
上表のCDBVariant::m_dwTypeでは、CDBVariantオブジェクトの共用体データメンバに現在格納されている値のデータ型が入る。<br> | |||
共用体にアクセスする前に、共用体のどのメンバにアクセスするかを決めるために、m_dwTypeの値をチェックする必要がある。<br> | 共用体にアクセスする前に、共用体のどのメンバにアクセスするかを決めるために、m_dwTypeの値をチェックする必要がある。<br> | ||
<br> | |||
下表は、m_dwTypeの値と対応する共用体メンバの一覧である。<br> | |||
<center> | <br> | ||
<center>表. m_dwType共用体メンバ</center> | |||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
170行目: | 170行目: | ||
</center> | </center> | ||
<br> | <br> | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
CString strCon = "DSN = SQLServerTest;"; | CString strCon = "DSN = SQLServerTest;"; | ||
179行目: | 178行目: | ||
try | try | ||
{ | { | ||
rs.Open( CRecordset::forwardOnly, _T("select * from test") );//SQLコマンドの実行 | rs.Open( CRecordset::forwardOnly, _T("select * from test") ); // SQLコマンドの実行 | ||
// 値を表示 | // 値を表示 | ||
while(!rs.IsEOF()) | while (!rs.IsEOF()) { | ||
for(short index = 0; index < rs.GetODBCFieldCount(); index++) { | |||
for(short index = 0; index < rs.GetODBCFieldCount(); index++) | |||
CDBVariant val; | CDBVariant val; | ||
rs.GetFieldValue( index,val); | rs.GetFieldValue(index, val); | ||
switch(val.m_dwType) | switch(val.m_dwType) { | ||
case DBVT_NULL : | case DBVT_NULL : | ||
TRACE("NULL 無効の値\n"); | TRACE("NULL 無効の値\n"); | ||
219行目: | 216行目: | ||
case DBVT_DATE : | case DBVT_DATE : | ||
TRACE("m_pdate TIMESTAMP_STRUCT 型のオブジェクトへのポインタ\n"); | TRACE("m_pdate TIMESTAMP_STRUCT 型のオブジェクトへのポインタ\n"); | ||
TIMESTAMP_STRUCT * | |||
// NULLチェック | |||
if (val.m_pdate != nullptr) { | |||
TIMESTAMP_STRUCT *pT = val.m_pdate; | |||
CString strDateTime; | |||
strDateTime.Format(_T("%04d/%02d/%02d %02d:%02d:%02d"), pT->year, pT->month, pT->day, pT->hour, pT->minute, pT->second); | |||
TRACE(_T("Field: %s, Value: %s\n"), fieldName, strDateTime); | |||
} | |||
break; | break; | ||
case DBVT_STRING : | case DBVT_STRING : | ||
TRACE("m_pstring CString 型のオブジェクトへのポインタ\n"); | if (val.m_pstring != nullptr) { | ||
TRACE("m_pstring CString 型のオブジェクトへのポインタ\n"); | |||
TRACE(_T("Field: %s, Value: %s\n"), fieldName, *val.m_pstring); | |||
} | |||
break; | break; | ||
case DBVT_BINARY : | case DBVT_BINARY : | ||
238行目: | 242行目: | ||
} | } | ||
} | } | ||
catch(...) | catch (CDBException *e) { | ||
TRACE(_T("Database error: %s\n"), e->m_strError); | |||
e->Delete(); | |||
} | |||
catch (...) { | |||
TRACE(_T("不明なデータベースエラーが発生\n")); | |||
} | } | ||
246行目: | 254行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:MFC]] | [[カテゴリ:MFC]] |
2025年1月11日 (土) 19:09時点における版
概要
ここでは、MFCとミドルウェアであるODBCを使用したデータベース処理を記載する。
上記を使用したデータベースの更新手順は、以下の2つの項目からなる。
- ODBCアドミニストレータでのデータソース登録
- データベースの操作
SELECT
#include <afxdb.h>
void CSampleDlg::OnBnClickedQueryButton1()
{
// 接続文字列生成
CString strCon = "DSN=MS Access 97 Database;UID=Admin;PWD=";
// Windows認証でSQLServerを使用する場合 => CString strCon = "DSN = SQLServerTest;";
// 接続
CDatabase db;
db.OpenEx( _T( strCon ), CDatabase::noOdbcDialog );
// db.OpenEx( _T( strCon ), CDatabase::openReadOnly | CDatabase::noOdbcDialog ); // 読み込み専用
// CDatabase::openReadOnly データソースを読み取り専用で開く
// CDatabase::noOdbcDialog 必要な情報が提供されているかに関わらず、ODBC接続のダイアログボックスを表示しない
// CDatabase::forceOdbcDialog ODBC接続のダイアログ ボックスを常に表示する
// 実行
CRecordset rs(&db);
try
{
// SQLコマンドの実行
rs.Open( CRecordset::forwardOnly, _T("select * from test") );
CODBCFieldInfo fi;
short nFields = rs.GetODBCFieldCount();
//フィールド名を表示
if (!rs.IsEOF())
{
for(short index = 0; index < rs.GetODBCFieldCount(); index++ )
{
rs.GetODBCFieldInfo(index, fi);
TRACE("%s\n",fi.m_strName);
}
}
// 値を表示
while( !rs.IsEOF() )
{
for(short index = 0; index < rs.GetODBCFieldCount(); index++)
{
CString strValue;
rs.GetFieldValue(index, _T(strValue));
TRACE("%s\n", strValue);
}
rs.MoveNext();
}
}
catch(...)
{ // SQLがエラーを発生した場合はここで捕捉
// メモリリークのように見えるがODBCドライバが自動的に解放する
}
rs.Close();
db.Close();
}
UPDATE / INSERT / DELETE
void CSampleDlg::OnBnClickedQueryButton2()
{
// 接続文字列生成
CString strCon = "DSN=MS Access 97 Database;UID = Admin; PWD = ";
CDatabase db;
// 接続
db.OpenEx(_T( strCon ), CDatabase::noOdbcDialog);
// db.OpenEx(_T( strCon ), CDatabase::openReadOnly | CDatabase::noOdbcDialog); // 読み込み専用
// CDatabase::openReadOnly データソースを読み取り専用で開く
// CDatabase::noOdbcDialog 必要な情報が提供されているかに関わらず、ODBC接続のダイアログ ボックスを表示しない
// CDatabase::forceOdbcDialog ODBC接続のダイアログボックスを常に表示する
// 実行
db.BeginTrans(); // トランザクション開始
try
{
db.ExecuteSQL("create table test(a text, b text)"); // 各種SQLコマンドの実行 複数実行可能
// db.ExecuteSQL("insert into test(a,b) values('inaba','minoru')"); // 各種SQLコマンドの実行 複数実行可能
// db.ExecuteSQL("delete from test where a='inaba'"); // 各種SQLコマンドの実行 複数実行可能
// db.ExecuteSQL("DROP TABLE test"); // 各種SQLコマンドの実行 複数実行可能
}
catch(...)
{ // SQLでエラーが発生した場合はここで捕捉できる
// メモリリークのように見えるがODBCドライバが自動的に解放する
}
db.CommitTrans(); // トランザクションの完了
db.Close();
}
注意点
SQL Server等でSELECT文を発行すると、datetime型カラム等が表示できない場合がある。
そのため、GetFieldValueメソッドの引数にCDBVariantを使用する。
メンバ変数名 | データ型 |
---|---|
m_boolVal | BOOL |
m_chVal | unsigned char |
m_dblVal | double |
m_dwType | DWORD(現在格納されている値のデータ型) |
m_fltVal | float |
m_iVal | short |
m_lVal | long |
m_pbinary | CLongBinaryオブジェクトへのポインタ |
m_pdate | TIMESTAMP_STRUCTオブジェクトへのポインタ |
m_pstring | CStringオブジェクトへのポインタ |
上表のCDBVariant::m_dwTypeでは、CDBVariantオブジェクトの共用体データメンバに現在格納されている値のデータ型が入る。
共用体にアクセスする前に、共用体のどのメンバにアクセスするかを決めるために、m_dwTypeの値をチェックする必要がある。
下表は、m_dwTypeの値と対応する共用体メンバの一覧である。
共用体データ型 | 共用体データメンバ |
---|---|
DBVT_NULL | 有効な共用体メンバはなく、アクセスできません。 |
DBVT_BOOL | m_boolVal |
DBVT_UCHAR | m_chVal |
DBVT_SHORT | m_iVal |
DBVT_LONG | m_lVal |
DBVT_SINGLE | m_fltVal |
DBVT_DOUBLE | m_dblVal |
DBVT_DATE | m_pdate |
DBVT_STRING | m_pstring |
DBVT_BINARY | m_pbinary |
CString strCon = "DSN = SQLServerTest;";
CDatabase db;
db.OpenEx(_T( strCon ), CDatabase::noOdbcDialog);
CRecordset rs( &db );
try
{
rs.Open( CRecordset::forwardOnly, _T("select * from test") ); // SQLコマンドの実行
// 値を表示
while (!rs.IsEOF()) {
for(short index = 0; index < rs.GetODBCFieldCount(); index++) {
CDBVariant val;
rs.GetFieldValue(index, val);
switch(val.m_dwType) {
case DBVT_NULL :
TRACE("NULL 無効の値\n");
break;
case DBVT_BOOL :
TRACE("m_boolVal BOOL 型\n");
TRACE("%d\n",val.m_boolVal);
break;
case DBVT_UCHAR :
TRACE("m_chVal unsigned char 型\n");
TRACE("%s\n",val.m_chVal);
break;
case DBVT_SHORT :
TRACE("m_iVal short 型\n");
TRACE("%d\n",val.m_iVal);
break;
case DBVT_LONG :
TRACE("m_lVal long 型\n");
TRACE("%d\n",val.m_lVal);
break;
case DBVT_SINGLE :
TRACE("m_fltVal float 型\n");
TRACE("%f\n",val.m_fltVal);
break;
case DBVT_DOUBLE :
TRACE("m_dblVal double 型\n");
TRACE("%f\n",val.m_dblVal);
break;
case DBVT_DATE :
TRACE("m_pdate TIMESTAMP_STRUCT 型のオブジェクトへのポインタ\n");
// NULLチェック
if (val.m_pdate != nullptr) {
TIMESTAMP_STRUCT *pT = val.m_pdate;
CString strDateTime;
strDateTime.Format(_T("%04d/%02d/%02d %02d:%02d:%02d"), pT->year, pT->month, pT->day, pT->hour, pT->minute, pT->second);
TRACE(_T("Field: %s, Value: %s\n"), fieldName, strDateTime);
}
break;
case DBVT_STRING :
if (val.m_pstring != nullptr) {
TRACE("m_pstring CString 型のオブジェクトへのポインタ\n");
TRACE(_T("Field: %s, Value: %s\n"), fieldName, *val.m_pstring);
}
break;
case DBVT_BINARY :
TRACE("m_pbinary\n CLongBinary 型のオブジェクトへのポインタ");
break;
default :
break;
}
}
rs.MoveNext();
}
}
catch (CDBException *e) {
TRACE(_T("Database error: %s\n"), e->m_strError);
e->Delete();
}
catch (...) {
TRACE(_T("不明なデータベースエラーが発生\n"));
}
rs.Close();
db.Close();