1. 程式人生 > >詳細介紹—獲取ACCESS資料庫中所有的表名(ODBC + MFC實現)解決方法

詳細介紹—獲取ACCESS資料庫中所有的表名(ODBC + MFC實現)解決方法

網上關於獲取ACCESS資料庫中所有的表名的文章挺多的,但是說的不是很詳細,對於初學者來說很難看懂(我也是初學者呵呵),研究了很久,自己弄懂後,覺得很有必要做個詳細的介紹,以免其他初學者向我一樣,因為研究這個東西走很多彎路從而浪費過多寶貴的時間。
  獲取ACCESS資料庫中所有的表名有什麼用呢?因為我們在很多地方會用到此功能的,例如做一個學習軟體,使用者可以自定義選擇不同的課文學習,如果資料庫中每一課對應一張表,那麼我們就很有必要再使用者點選“選擇課文”按鈕後,彈出一個對話方塊,列出所有課文(即所有表名)供使用者選擇,因此如果你還沒有實現過此功能的話,是很有必要繼續往下看滴。
  實現此功能主要用到下面兩個語句,待會再慢慢說明,如果你已經對這兩個語句已經很熟悉了,那就請繞道了哈。


CString strSql = “select name from MSysObjects where type=1 and flags=0"
recordset.GetFieldValue("name", strTableName);

不管它,我們先往下看。
首先,這裡有一點點需要了解的知識
1,ACCESS資料庫裡有幾張隱藏的表,其中一張表為MSysObjects,即系統表,裡面記錄得有一些我們建立的表的資訊,(例如裡面有多少張表,表的名字、建立時間等等),很明顯,我們就是要從這張系統表中獲取我們要的表名(我們自己建立的表的名字)。因為系統表MSysObjects是預設隱藏的,我們只要:工具->選項->檢視(勾上“系統物件”選項)即可看到。


2,看到MSysObjects後,我們雙擊進去看一下。我們會看到表的Name欄位下記錄得有我們自己建立的表的名字(這就是我們要獲取的表名),而且我們自己建立的表對應的Flags欄位的值都等於0,對應的Type欄位的值都等於1(看不到Type欄位的話可以把視窗往右邊拉)。

3,因為MSysObjects也是一張表,所以我們當然可以用Sql語句將其中的所有表名選出來,
即剛才那句:“select name from MSysObjects where type=1 and flags=0"

意思就是:從系統表MSysObjects的Name欄位中,選出Type等於1且Flags等於0的項。(符合要求的就只剩下我們建立的所有表的名字了,搞定!)


4,關於系統表MSysObjects許可權的問題,後面會說到,我們先往下看。

注:因為本文主要是說明獲取ACCESS資料庫中所有的表名的問題,那些關於開啟、連線資料庫、關於記錄集和配置資料來源(ODBC)的知識就不說了,可以參考MSDN關於CDatabase和CRecordset這兩個類。因為你能看到這裡,肯定已經知道怎麼連線資料庫,怎麼用CRecordset類的函數了。

繼續話題,執行剛才的Sql語句得要用CRecordset類的Open函式:
CString strSql = “select name from MSysObjects where type=1 and flags=0"
recordset.Open(AFX_DB_USE_DEFAULT_TYPE, strSql);//這兩句應該沒問題,備註略

接下來我們得用到CRecordset類的GetFieldVal()函式

用法:
CString strTableName;
recordset.GetFieldValue("name", strTableName); //將Name儲存到strTableName

// 注意:這裡只是將MSysObjects其中的Name欄位下的一個值(表名)賦給strTableName
//其他的表名還得用一個迴圈來依次儲存

While(!recordset.IsEOF())//當記錄集recordset後面還有值
{
recordset.GetFieldValue("name", strTableName); //將Name儲存到strTableName
//我們自己的程式碼,(例如列出表名:m_listBox.AddString(strTableName))
  recordset.MoveNext();//移動到下一個值
}



供參考完整程式碼:

//對話方塊初始化時在列表框(ListBox)中顯示所有表名
BOOL CShowTableNameDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//開啟資料庫
CDatabase db;
// myDataSourceName為資料來源名,請參考CDatabase類
  db.Open(_T("myDataSourceName"), FALSE, FALSE, _T("ODBC;"), FALSE);

CRecordset recordset(&db);//不要忘記將&db做引數
  CString strSql;
  strSql = _T("select name from MSysObjects where type=1 and flags=0");//詳見上文
recordset.Open(AFX_DB_USE_DEFAULT_TYPE, strSql);//

CString strTableName;//儲存表名

while(!recordset.IsEOF())
{
recordset.GetFieldValue("name", strTableName);//見上文
//列出所有表名到列表框上
  // m_listBox_showDbTable為關聯了列表框的變數
this->m_listBox_showDbTable.AddString(strTableName);
  recordset.MoveNext();
}

recordset.Close();
db.Close();

return TRUE;  
}

注意:當我們執行程式碼的時候,我們會發現報錯:“…沒有讀取許可權”,因為系統表MSysObjects預設的許可權是連管理員都不能訪問,所以我們還得設定一下:
工具 ->安全 ->使用者與組許可權,選中MSysObjects,給個“讀取資料”許可權就夠了(“讀取設計”許可權會自動加上)。
再次執行,我們會看到,所有的表名都顯示在列表框(ListBox)上了。

另外,GetFieldValue("name", strTableName); 這個語句很容易誤解,我們很容易覺得是它已經將所有表的名字賦值給strTableName了,其實只是賦值了記錄集recordset的第一個值而已,我們還得繼續一個一個第把值賦給strTableName。

就是說,GetFieldValue("name", strTableName);中的引數 “name”其實是表示系統表MSysObjects的name欄位,通過Sql語句,我們把name欄位符合條件的表名選了出來,例如有name1、name2、name3被選出來了,通過GetFieldValue("name", strTableName)把第一個name1賦給了strTableName,接下來記錄集往後移動:recordset.MoveNext();再通過GetFieldValue("name", strTableName)把第2個name2賦給了strTableName,….