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

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
(Wiki がページ「ODBCでデータベースを更新する」を「ODBCでデータベースを更新する(MFC)」に、リダイレクトを残さずに移動しました)
(Wiki がページ「ODBCでデータベースを更新する(MFC)」を「MFCとデータベース - CRUDの実行」に、リダイレクトを残さずに移動しました)
(相違点なし)

2021年1月29日 (金) 16:40時点における版

概要

ここでは、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
    {
       rs.Open( CRecordset::forwardOnly, _T("select * from test") );//SQLコマンドの実行
 
       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();
 }



注意点

SQLServer等でSELECT文を発行すると、上記のコードではdatetime等が表示できない場合がある。
そのため、GetFieldValueの引数にCDBVariantを使用する。

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

表1. 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");
                TIMESTAMP_STRUCT *pT;
                pT = val.m_pdate;
                TRACE("%d/%d/%d %d:%d:%d\n",pT->year,pT->month,pT->day,pT->hour,pT->minute,pT->second );
                break;
             case DBVT_STRING :
                TRACE("m_pstring CString 型のオブジェクトへのポインタ\n");
                TRACE("%s\n",*val.m_pstring);
                break;
             case DBVT_BINARY :
                TRACE("m_pbinary\n CLongBinary 型のオブジェクトへのポインタ");
                break;
             default :
                break;
          }
       }
 
       rs.MoveNext();
    }
 }
 catch(...)
 {
 }
 
 rs.Close();
 db.Close();