第一次写文章,大家支持下~~详细介绍—获取ACCESS数据库中所有的表名(ODBC + MFC实现)
详细介绍—获取ACCESS数据库中所有的表名(ODBC + MFC实现)
作者:叶秀标 日期:2011-03-21 CSDN:lovestevevai
网上关于获取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,….
看到这里,我想大家应该搞清楚了刚才的那几个疑问了。
1,为什么这里的Sql语句要这样写?
“select name from MSysObjects where type=1 and flags=0"
2,为什么要type=1 and flags=0 ?
3,GetFieldValue("name", strTableName)里为什么第2个参数是name,从哪里跑出来的?
怎么实现获取ACCESS数据库中所有的表名,也应该明白了。
[解决办法]
LZ你这样骗可用分?
[解决办法]
建议提供代码下载,可以上传到自己的资源里~
[解决办法]
为啥不放到BLOG里面?