●●●● 基于dialog的程序怎么访问数据库?谢谢 ●●●●

时间:2022-11-01 13:44:45
书上的例子是基于文档的,但我的程序是基于dialog的,在用向导建立工程的时候没有提供数据库支持,于是我就用new class加入一个CRecordset类,其成员变量可以跟记录字段绑定,例如:

Column Name        Type           Member
ip地址            CString         m_strIP
进程列表          CString         m_strProList

但书上可以把控件ID跟记录字段绑定,在classwizard里的Member Variables的classname里选CYourProjectView(而基于dialog的是没有view的),选择控件ID,Add Variables,就可以出现一系列m_pSet成员变量,是CRecordset派生类的指针,这样就可以将控件ID和m_pSet成员关联,然后用m_pSet->AddNew()就可以将对应的控件内容写入数据库。
但基于dialog的根本就找不到有什么m_pSet成员,怎么回事?是不是要再加CRecordView类,或者缺少什么头文件?我已包含了afxdb.h

说了这么多也不知道大家明不明白,总之就是一句话,基于dialog的程序怎么访问数据库?谢谢

66 个解决方案

#1


用ado吧,功能强大,操作简单!网上也有不少资料!

#2


在new class的向导中生成一个基于CRecordset的新类如:myrecordset;
重载
DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(b093)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[ip地址]"), m_strIP);
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
}
在dialog的声明中加入
CDatabase db;
myrecordset rs;
在OnInitDialog()中加入
db.Open("odbcname",false,false,"ODBC;UID=userid;PWD=password");
rs.m_pDatabase=&db;
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from usertable");
然后在dialog的classwizard中加入myrecordset作为Foreign class,这样在dialog的classwizard中就可以将控件ID和rs成员关联了.

#3


先在
stdafx.h
中加入
#include <afxdb.h>
或者
#include <afxdao.h>
然后就可以和其他的应用程序一样的使用数据库了

#4


CFormView

#5


列表框中的内容也可以通过跟rs成员相连写入数据库吗
那我想把成员变量直接跟rs成员关联可以吗,这样会比较方便

#6


应该可以

#7


1.在文件Stdafx.h 文件的末尾添加
#include <afxdb.h>

2.在文本模式下编辑RC文件,在下面的语句后
"#include ""afxprint.rx""//printing/print preview resources\r\n"

添加
"#include""afxdb.rc""//database resources\r\n"

在下面的语句后
"#include""afxprint.rc" //printing/print preview resources
添加
#include"afxdb.rc" //database resources

#8


m_pSet当然是自己设置的成员变量

wizard肯定是可以绑定的

注意包含头文件

#9


用ado最简单

#10


用odbc 
在new class的向导中生成一个基于CRecordset的新类如:myrecordset;

#11


myrecordset *m_pSet;

m_pSet->AddNew();编译通过,运行出错

如果是基于文档的程序就可以,why?

#12


因为基于文档时和基于对话框时,你的基类都不一样!

#13


那该怎么做呢,我在dialog中加了myrecordset *m_pSet数据成员,但只要有m_pSet->就会出错,那位大虾给说说?谢了

#14


是不是只要声明了加了myrecordset *m_pSet就可以使用m_pSet成员访问数据库了?但不行啊,别的还要什么吗

#15


你都没打开数据库,操作怎么会不非法?
OnInitDialog()中
{
CString  sDSN="ODBC;DRIVER=Microsoft Access Driver (*.mdb);DSN='';DBQ=aaa.mdb;PWD=aaa";

m_database = new CDatabase;
if(!m_database->Open(NULL,FALSE,FALSE,sDSN,FALSE))
{      
CDialog::EndDialog(0);
return FALSE;
}

CString strSQL="select * from 销售";
m_pSet = new CRecordset(m_database);
m_pSet->Open(CRecordset::dynaset,strSQL);
}

#16


在头文件里加myrecordset *m_pSet;
在OnInitDialog()中加m_pSet->Open();
OK了?

#17


再加点分

kingzai()():可以QQ联系吗,25109707

#18


还是不行

#19


http://www.vckbase.com/code/listcode.asp?mclsid=11&sclsid=1105
有一个示例,照着看看把

#20


再推……

#21


算了,转到数据库版吧,估计没用

#22


最简单的是ODBC,你建立一个数据源,而后打开数据源,就可以连接上数据库了。

#23


我在inser一个CRecordset类的时候已经指定一个数据源了,但用CRecordset类怎么打开数据源并连接?是sql server

#24


打开数据源是用cdatabase类打开的,我在上面已说过了,如果你需要我可以邦你做个DEMO

#25


small_wei(small) :按你的方法做了,现在的问题是,我dialog上的控件ID都已经跟原有的成员变量相关联了,我再将它们跟rs成员相连的时候就不行了,怎么办?
我想把rs成员跟ID原来对应的变量直接相连,可以吗?

#26


控件ID只能与一种变量关联,那么与rs成员关联,要么与ID原来对应的变量关联,如果你想与rs成员关联的话,先将与ID想关联的变量删除.

#27


我的那些控件ID试没用的,因为程序界面是要隐藏的,我的目的是想把ID对应的变量跟rs关联,其实就是想把那些变量写入数据库

#28


用CDataSource类

#29


RS就没有必要与ID关联了,直接使用ID对应的变量给rs内的数据库字段变量付值就行了如你有个ID对应的变量strIP;

RFX_Text(pFX, _T("[ip地址]"), m_strIP);//数据库字段变量
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
写入数据库
rs.Edit(); 或rs.AddNew();
rs.m_strIP=strIP;
rs.update();

读出数据库
strIP=rs.m_strIP;

#30


楼上的,这个类怎么用?我英文很烂,现在也没时间查msdn了

#31


我刚开始答复时已经说清楚了,最后两行是关于关联问题的,不看就行了.

#32


small_wei(small):我以前就是这样用的,但好像不行,我再试试

#33


我一直是这样做的,没有问题的,出什么错,能不能把程序贴上,或mail给我.

#34


好的,我再试试,如果还不行的话就把程序mail给你

#35


好的,我等着

#36


不行啊,按你的方法,编译没问题,但执行时说“非法的描述器索引”?

#37


还是将程序MIAL给我吧.

#38


好的
问题出在
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from 进程监控信息表");
这句

#39


数据库打开没有
Cdatabase db;
db.Open(...);
rs.m_pDatabase=&db;//这个很关键

#40


有啊
db.Open("new",false,false,"ODBC;UID=kkk;PWD=111"); //new是数据源
rs.m_pDatabase=&db;
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from 进程监控信息表");

#41


会不会是数据库的原因,检查一下,我建成一个环境测试一下,问一下,是什么数据库?

#42


是sql
我已经把工程mail给你了

#43


DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(b093)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[ip地址]"), m_strIP);
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
}
在DoFieldExchange中的变量m_strIP要与你打开的数据库进程监控信息表中的字段一一对应.
我在这里测试没有问题

#44


你在DoFieldExchange中定义的变量是由classwizard自动生成的呢,还是手工输入的呢,我感觉这里有问题,你能告诉我进程监控信息表中定义所有的安段吗?

#45


在classwizard中生成的

主机名       char       20
ip地址       char       15
进程号       bigint     8
进程名       char       50
事件时间     datatime   10
事件信息     char       10
日期         datatime   10

#46


[dbo].[进程监控信息表].[ip地址]
把[dbo].[进程监控信息表]删除,只留下[ip地址]试试

#47


你这里只有7个字段,但在程序中却有8个字段,多了[事件内容],

#48


如果你在DoFieldExchange中定义的变量是由classwizard自动生成的话,为什么
RFX_Text(pFX, _T("[事件信息]"), m_strEventMeg);
RFX_Text(pFX, _T("[dbo].[进程监控信息表].[ip地址]"), m_strIP);
会不同呢???

#49


因为我这里要对两个表操作啊,出错信息表和进程监控信息表

CString CInserRecord::GetDefaultSQL()
{
return _T("[dbo].[出错信息],[dbo].[进程监控信息表]");
}

里面有一些字段是相同的,我就只留其中一个了
那个事件内容是出错信息表里的

#50


是不是两个表不能这样操作?

#1


用ado吧,功能强大,操作简单!网上也有不少资料!

#2


在new class的向导中生成一个基于CRecordset的新类如:myrecordset;
重载
DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(b093)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[ip地址]"), m_strIP);
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
}
在dialog的声明中加入
CDatabase db;
myrecordset rs;
在OnInitDialog()中加入
db.Open("odbcname",false,false,"ODBC;UID=userid;PWD=password");
rs.m_pDatabase=&db;
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from usertable");
然后在dialog的classwizard中加入myrecordset作为Foreign class,这样在dialog的classwizard中就可以将控件ID和rs成员关联了.

#3


先在
stdafx.h
中加入
#include <afxdb.h>
或者
#include <afxdao.h>
然后就可以和其他的应用程序一样的使用数据库了

#4


CFormView

#5


列表框中的内容也可以通过跟rs成员相连写入数据库吗
那我想把成员变量直接跟rs成员关联可以吗,这样会比较方便

#6


应该可以

#7


1.在文件Stdafx.h 文件的末尾添加
#include <afxdb.h>

2.在文本模式下编辑RC文件,在下面的语句后
"#include ""afxprint.rx""//printing/print preview resources\r\n"

添加
"#include""afxdb.rc""//database resources\r\n"

在下面的语句后
"#include""afxprint.rc" //printing/print preview resources
添加
#include"afxdb.rc" //database resources

#8


m_pSet当然是自己设置的成员变量

wizard肯定是可以绑定的

注意包含头文件

#9


用ado最简单

#10


用odbc 
在new class的向导中生成一个基于CRecordset的新类如:myrecordset;

#11


myrecordset *m_pSet;

m_pSet->AddNew();编译通过,运行出错

如果是基于文档的程序就可以,why?

#12


因为基于文档时和基于对话框时,你的基类都不一样!

#13


那该怎么做呢,我在dialog中加了myrecordset *m_pSet数据成员,但只要有m_pSet->就会出错,那位大虾给说说?谢了

#14


是不是只要声明了加了myrecordset *m_pSet就可以使用m_pSet成员访问数据库了?但不行啊,别的还要什么吗

#15


你都没打开数据库,操作怎么会不非法?
OnInitDialog()中
{
CString  sDSN="ODBC;DRIVER=Microsoft Access Driver (*.mdb);DSN='';DBQ=aaa.mdb;PWD=aaa";

m_database = new CDatabase;
if(!m_database->Open(NULL,FALSE,FALSE,sDSN,FALSE))
{      
CDialog::EndDialog(0);
return FALSE;
}

CString strSQL="select * from 销售";
m_pSet = new CRecordset(m_database);
m_pSet->Open(CRecordset::dynaset,strSQL);
}

#16


在头文件里加myrecordset *m_pSet;
在OnInitDialog()中加m_pSet->Open();
OK了?

#17


再加点分

kingzai()():可以QQ联系吗,25109707

#18


还是不行

#19


http://www.vckbase.com/code/listcode.asp?mclsid=11&sclsid=1105
有一个示例,照着看看把

#20


再推……

#21


算了,转到数据库版吧,估计没用

#22


最简单的是ODBC,你建立一个数据源,而后打开数据源,就可以连接上数据库了。

#23


我在inser一个CRecordset类的时候已经指定一个数据源了,但用CRecordset类怎么打开数据源并连接?是sql server

#24


打开数据源是用cdatabase类打开的,我在上面已说过了,如果你需要我可以邦你做个DEMO

#25


small_wei(small) :按你的方法做了,现在的问题是,我dialog上的控件ID都已经跟原有的成员变量相关联了,我再将它们跟rs成员相连的时候就不行了,怎么办?
我想把rs成员跟ID原来对应的变量直接相连,可以吗?

#26


控件ID只能与一种变量关联,那么与rs成员关联,要么与ID原来对应的变量关联,如果你想与rs成员关联的话,先将与ID想关联的变量删除.

#27


我的那些控件ID试没用的,因为程序界面是要隐藏的,我的目的是想把ID对应的变量跟rs关联,其实就是想把那些变量写入数据库

#28


用CDataSource类

#29


RS就没有必要与ID关联了,直接使用ID对应的变量给rs内的数据库字段变量付值就行了如你有个ID对应的变量strIP;

RFX_Text(pFX, _T("[ip地址]"), m_strIP);//数据库字段变量
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
写入数据库
rs.Edit(); 或rs.AddNew();
rs.m_strIP=strIP;
rs.update();

读出数据库
strIP=rs.m_strIP;

#30


楼上的,这个类怎么用?我英文很烂,现在也没时间查msdn了

#31


我刚开始答复时已经说清楚了,最后两行是关于关联问题的,不看就行了.

#32


small_wei(small):我以前就是这样用的,但好像不行,我再试试

#33


我一直是这样做的,没有问题的,出什么错,能不能把程序贴上,或mail给我.

#34


好的,我再试试,如果还不行的话就把程序mail给你

#35


好的,我等着

#36


不行啊,按你的方法,编译没问题,但执行时说“非法的描述器索引”?

#37


还是将程序MIAL给我吧.

#38


好的
问题出在
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from 进程监控信息表");
这句

#39


数据库打开没有
Cdatabase db;
db.Open(...);
rs.m_pDatabase=&db;//这个很关键

#40


有啊
db.Open("new",false,false,"ODBC;UID=kkk;PWD=111"); //new是数据源
rs.m_pDatabase=&db;
rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from 进程监控信息表");

#41


会不会是数据库的原因,检查一下,我建成一个环境测试一下,问一下,是什么数据库?

#42


是sql
我已经把工程mail给你了

#43


DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(b093)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[ip地址]"), m_strIP);
RFX_Text(pFX, _T("[进程列表 ]"), m_strProList);
}
在DoFieldExchange中的变量m_strIP要与你打开的数据库进程监控信息表中的字段一一对应.
我在这里测试没有问题

#44


你在DoFieldExchange中定义的变量是由classwizard自动生成的呢,还是手工输入的呢,我感觉这里有问题,你能告诉我进程监控信息表中定义所有的安段吗?

#45


在classwizard中生成的

主机名       char       20
ip地址       char       15
进程号       bigint     8
进程名       char       50
事件时间     datatime   10
事件信息     char       10
日期         datatime   10

#46


[dbo].[进程监控信息表].[ip地址]
把[dbo].[进程监控信息表]删除,只留下[ip地址]试试

#47


你这里只有7个字段,但在程序中却有8个字段,多了[事件内容],

#48


如果你在DoFieldExchange中定义的变量是由classwizard自动生成的话,为什么
RFX_Text(pFX, _T("[事件信息]"), m_strEventMeg);
RFX_Text(pFX, _T("[dbo].[进程监控信息表].[ip地址]"), m_strIP);
会不同呢???

#49


因为我这里要对两个表操作啊,出错信息表和进程监控信息表

CString CInserRecord::GetDefaultSQL()
{
return _T("[dbo].[出错信息],[dbo].[进程监控信息表]");
}

里面有一些字段是相同的,我就只留其中一个了
那个事件内容是出错信息表里的

#50


是不是两个表不能这样操作?