## 数据库综合开发实践 马磊、张万里
一套原来在Access上开发的桌面系统，网页调阅使用ASP编程，数据维护系统使用C++Builder编程。由于Access是一个桌面的共享型数据库，所以在通用性和网络开发方面都存在一些问题。因此，需要将该系统移植到服务器型的数据库上。使系统既可以通过桌面软件维护数据，又可以有大量用户通过网页调看数据（结果）。
系统初始软件为：Windows98第二版、Access97、C++Builder4.0、C++Builder5.0、MDAC（Microsoft Data Access Component 2.6中文版）。
一、移植到Oracle的尝试
在机器上安装Oracle 7.3桌面版，由于使用不熟练，所以选择默认安装，除选择语言Simplified Chinese外，其他都选择默认，一路装下去，没有问题，重新启动系统。运行Net Easy Config，配置需要的数据库别名，然后用SQL Net连接试验，用户名输入system，密码输入manager，连接服务器注意，不要输入服务器的地址，而是输入刚才建立的别名，进去了。Ok！
此时开始测试ODBC，建立ODBC数据源。此时，ODBC中有两个有关Oracle的驱动，一个是Microsoft ODBC for Oracle，另一个是Oracle 7.3，这是该公司自己开发的驱动。可是怎么选择驱动程序都不行，不是提示Oracle的驱动没有安装，就是说某个DLL文件找不到。真是说不行，就不行，行也不行。
多次试验均无效。。。。
检查AUTOEXEC.BAT文件，其中有ORACLE的路径。那末，问题会在什么地方呢？本着怀疑一切的态度，在MSDOS方式下随手输入了一个PATH命令，奇怪，里面居然没有ORACLE的路径！打开AUTOEXEC.BAT文件一琢磨，路径是不是太长？把路径中的其他目录全都注释掉，重启系统，嘿！数据源可以建立了，而且两个驱动程序哪个都能够工作。原来由于系统中安装了C++Builder的两个版本，而该软件的目录又特别深，造成PATH环境变量的溢出，而在WINDOWS环境下启动时的提示我们看不到，所以没有发现这个问题。现在知道了，重新调整一下AUTOEXEC.BAT文件，保留一个C++Builder的路径。以后得记住安装C++Builder时最好自己指定一个目录，这样可以缩短路径。这可是说行就行，不行也行。
经过对Oracle的测试，发现将Access数据库直接移植到Oracle数据库中时，对文本字段（TEXT，MEMO）的迁移总有问题，且该系统使用、安装过于复杂，对机器配置的要求也太高，而该系统需要安装的用户较多，且使用者水平参差不齐，所以决定改用现在在自由软件界比较流行的免费数据库系统MySQL。
二、移植到MySQL的经历
1．该系统的安装比较简单，若认为自己没有能力安装该软件的话，还可以从网络上下载一个叫PHPTriad for windows的软件，该软件安装时没有任何选项，自动安装好MySQL。（实际上，该软件同时还安装好了APACHE服务器、PHP语言解释器，这正好符合将来把ASP的网页换到PHP上去;另外，该软件还同时安装配置好了一个网页数据库维护工具PHPMyAdmin，PHPMyAdmin对于SQL语言不算熟的人来说管理数据库极其方便。）
2．再安装MYODBC（即ODBC for MySQL，我的是2.5版本），注意下载该软件时，要分清95版还是NT版的。安装也很简单，一路OK。好了，建立数据源work，填好IP地址，数据库名填mymember(这时系统提供的数据库)，进行测试，不行？改用系统自动安装的sample-mysql数据源连接，链上了。仔细检查配置，没有错误，为什么系统自己做的数据源可以用，我做的就不行呢？把自己建立的删掉，把sample-mysql改名为work，再连接，嘿嘿，不行了！哈哈，原来就出在名字上，在work后面加上-mysql，再连接，好了，原来myodbc要求它的数据源名称必须以mysql结尾！解决了数据源，下面开始移植原来的Access数据库。
移植工作比较简单，打开Access数据库，选中第一张表，从File菜单中选择“另存为/导出”，选择“另存为一个外部文件或数据库”,选确定，在弹出的对话框中的“保存类型”下拉选单中选择“ODBC数据库”，又弹出一个“导出”的对话框，如果打算给该数据表改名的话，现在可以输入新的名字，然后选择确定，在弹出的“选择数据源”对话框中点Machine Data Source（机器数据源），找到自己建立的work-MySQL数据源，按确定。此时会回到Access数据库，如果数据表很大的话，状态栏中会有一个导出的进度，否则，导出已经完成。
导出成功后，通过PHPMYADMIN检查导出的数据库，结构、内容都正常。需要注意的是，如果数据表中用到了Access提供的ID（自动增量）字段的话，需要手工在目标数据库中修改对应字段的属性（这在PHPMyAdmin中很容易实现，找到该字段后点“改变”，在该字段的属性最后一项“额外”的下拉选单中选择auto_increment，然后保存。PHPMyAdmin的界面是英文的？其实只要在安装有PHPMyAdmin的目录Apache\Htdocs\PHPMyAdmin中找到config.inc.php文件，搜索require，把引号中的“english.inc.php”改成“chinese_gb.inc.php”,再去调用网页中的PHPMyAdmin，嘻嘻，是不是变成中文了？其实chinese_gb.inc.php是一个文件名，就在该目录下，你还可以把界面变成BIG5码呢）。
3．终于把移植的工作做完了，下面开始用C++BUILDER编程。对数据库使用ADO来访问。步骤如下：在ADO控件标签中选ADOTable，在主窗口上先放置一个ADOTable1，然后点击左边对象观察器（Object Inspector）中ConnectionString右边的“…”图标，选“Use Connection String”，点“Build”，在“Provider”标签中选择“Microsoft OLE DB Provider for ODBC Drivers”，点“Next>>”按钮，在“specify the source of data”中选“use data source name”,从下拉选单中选择数据源work-MySQL，点“Test Connection”，显示连接成功，确定，OK，返回，在对象观察器中Table Name属性点下拉选单，选择需要的数据表。再从Data Access控件标签中选DataSource，在主窗口上放置一个DataSource1，在对象观察器中DataSet属性点下拉选单，选择ADOTable1，下面进行界面输出的布局，选择“Data Controls”控件标签中的DBEdit根据需要放置，并把DataSource属性设置为DataSource1 ，DataField属性设置为所需要的字段名。如此放置几个字段，最后从“Data Controls”控件标签中选“DBNavigator”放在窗口上。再把ADOTable1的Active属性改为true，咦，怎么有的字段显示成(MEMO)，先不管他，运行程序，输入一些内容，点击提交，怎么没了？有的字段还缩短了，多试几次，发现新输入的内容不能超过原来的长度，那么原来是空的字段就永远没法输入内容了。这是怎么回事？这种用法肯定没有问题，以前在Access数据库上就是这么用的。那么，就是MySQL的ODBC有问题，退出C++Builder，打开数据源的选项仔细分析，其中第一项vaaaa很象。把它选中，确定，重新运行C++Builder，再运行程序，一切OK。原来MySQL这样的自由软件，其ODBC选项很多，是为了适应各方面需要，不象微软或其他的数据库那样默认值就可以用。这个选项可能是为了优化一些网络上的应用，而把数据库字段的默认值总是假设为最小状态，从而造成这个问题。这可能也是自由软件的一个小缺点吧。
三、ASP访问MySQL数据库的问题
原来的主页中大量使用了ASP访问数据库，其中典型的用法是：
dim LK_CONN
set LK_CONN=server.createobject("ADODB.CONNECTION")
LK_CONN.open "onduty_mysql","root",""
‘以上建立数据库的连接
dim RS_NEWS
set RS_NEWS = server.createobject("adodb.recordset")
sql = "SELECT * FROM NewsPic"
RS_NEWS.open sql,LK_CONN,1,1
‘以上建立对表的访问
‘下面显示内容，为表达简单，没有格式，引号中为字段名
=RS_NEWS("Extract")
=RS_NEWS("Pic")
这一段代码没有问题，实现了平滑过渡；但是有个别地方，有写入操作，数据不能正常读出。该段代码如下：
dim RS_COUNT
set RS_COUNT = server.createobject("adodb.recordset")
RS_COUNT.open "SELECT * FROM count",LK_CONN,3,3
'访问计数器
dim Zcount
Zcount=RS_COUNT("Count")
Zcount = Zcount + 1
RS_COUNT("Count").Value=Zcount
RS_COUNT.Update
RS_COUNT.Close
开始怀疑这一段后面有写入操作，所以不能正确执行，但经过仔细比较和测试，发现问题不在是否写入上。这一段的代码主要是用了ASP访问Access数据库时直接填入数据库名的方法，而没有使用SQL语句，我们把打开数据库的地方改为“select * from 表名”，程序遂工作正常。
结论：编程时应该尽量使用通用性好的方法，这样对于系统的通用性、可移植性来说，还是很重要的。
四、ODBC的问题
在C++Builder中有的地方要用到SQL查询，因此，有一段程序使用的是ADOQuery控件，本来这种用法在其他机器上用过，没有问题，可是在这里却不行。具体情况如下：放置一个ADOQuery，ConnectionString属性、TableName属性和前面的ADOTable属性设置一样，Active属性保持false，再添加一个DataSource控件和几个DBText控件，设置同前。然后在FormCreate(表单构造函数)中添加如下代码：
ADOQuery1->Active=false;
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select * from Names order by ID");
ADOQuery1->Active=true;
while (!ADOQuery1->Eof)
{
ComboBox1->Items->Add(ADOQuery1->FieldByName("Name")->AsString);
ADOQuery1->Next();
}
//后一段
ADOQuery1->Active=false;
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select * from Dutys order by ID");
ADOQuery1->Active=true;
while (!ADOQuery1->Eof)
{
ComboBox2->Items->Add(ADOQuery1->FieldByName("Duty")->AsString);
ADOQuery1->Next();
}
就这么一段代码，在该机器上怎么都不能运行，系统总是提示“BOF或EOF中有一个为真。。。。”的错误，将注释后面的一段删掉，系统可以运行，但退出程序时出现非法错误，说明是带故障运行。反复查看找不出程序的明显错误，把程序拿到其他机器上可以通过，两个机器的最主要差别就是ODBC的版本不同。
于是想将ODBC降为2.5英文版，找到MDAC2.5版安装了几次都不行，只好手工删除了，在WINDOWS目录中搜索出所有前缀为ODBC的文件，然后删除program files\common files中的system目录，再重新安装MDAC（Microsoft Data Access Component 2.5英文版），再运行该程序，一切正常。
结论：不知道是MDAC2.6版本的问题，还是因为它是中文版的问题，总之，造成系统的兼容性不是很好，建议大家在编程时也应该尽量使用已经熟悉的环境，而不要总是去尝试太新的东东。
当然，如果是我这一段代码有问题，还希望有高手能出来指导。
以上是我们在一次数据库系统的移植开发过程中出现问题和解决方法的真实记录，虽然问题都很小，但是让我们在开发过程中走了不少弯路，所以把它记录下来，供大家参考，希望对朋友们的开发有所帮助。其中的问题也希望有朋友能够指出更好的解决办法。