「MFCとデータベース - CRUDの実行」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
編集の要約なし
106行目: 106行目:


== 注意点 ==
== 注意点 ==
SQLServer等でSELECT文を発行すると、上記のコードではdatetime等が表示できない場合がある。<br>
SQL Server等でSELECT文を発行すると、datetime型カラム等が表示できない場合がある。<br>
そのため、GetFieldValueの引数にCDBVariantを使用する。<br><br>
そのため、GetFieldValueメソッドの引数にCDBVariantを使用する。<br>
 
<br>
<center>'''表1. CDBVariantのメンバ'''</center>
<center>. CDBVariantのメンバ</center>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
137行目: 137行目:
</center>
</center>
<br>
<br>
上記に記載したCDBVariant::m_dwTypeにおいて、<br>
上表のCDBVariant::m_dwTypeでは、CDBVariantオブジェクトの共用体データメンバに現在格納されている値のデータ型が入る。<br>
CDBVariantオブジェクトの共用体データメンバに現在格納されている値のデータ型が入る。<br>
共用体にアクセスする前に、共用体のどのメンバにアクセスするかを決めるために、m_dwTypeの値をチェックする必要がある。<br>
共用体にアクセスする前に、共用体のどのメンバにアクセスするかを決めるために、m_dwTypeの値をチェックする必要がある。<br>
次の表は、m_dwTypeの値と対応する共用体メンバの一覧である。<br>
<br>
 
下表は、m_dwTypeの値と対応する共用体メンバの一覧である。<br>
<center>'''表1. m_dwType共用体メンバ'''</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 *pT;
                pT = val.m_pdate;
                // NULLチェック
                TRACE("%d/%d/%d %d:%d:%d\n",pT->year,pT->month,pT->day,pT->hour,pT->minute,pT->second );
                 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("%s\n",*val.m_pstring);
                  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つの項目からなる。

  1. ODBCアドミニストレータでのデータソース登録
  2. データベースの操作



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を使用する。

表. 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の値と対応する共用体メンバの一覧である。

表. 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();