| | |
| | |
摘要:本文提供了在FOXBASE环境上开发管理信息系统,并与ORACLE7进行数据 交换的一种通用程序设计方法。仅供同行参考。 一 引言 随着改革开放的不断深入,计算机管理信息系统(MIS)的建设方兴末艾,并日益 发挥着越来越重要的作用。我们在MIS开发过程中,必须注意尽量利用原有软硬件资 源,解决好新旧平台之间的接口,保证共享数据库与子系统之间、子系统与子系统 之间的数据自动交换,从而达到节省投资、避免重复开发、缩短开发周期、提高工 作效率之目的。 在实际工作中,我们发现不少单位在规划、建设MIS网络之初,引进、移植或自 行开发了不少应用软件,其中还包括上级部门下达的、强制推广的行业性软件,而 这些应用软件大都是用DBASE、XBASE开发的。但是,随着工作的深入和计算机技术 的发展,以及行业标准的统一制定与实施,ORACLE关系数据库管理系统(RDBMS)作为 一个高性能的数据库管理系统,可以通用于八十多种大、中、小及微型计算机,它 采用了标准的SQL语言,具有丰富的第四代语言工具,因而正在我国迅猛推广运用。 那么如何实现ORACLE与DBASE的联合操作,进行数据转换呢?我们利用了ORACLE公 司的产品ORACLE DBXL转换工具。 DBXL是ORACLE V5.1和DBASE的接口产品。使用它可以将DBASE 编写的程序编译 成操作系统可执行的二进制文件,该执行文件可以访问存贮于ORACLE数据库的数据。 DBXL不仅可以作为DBASE的编译器,给DBASE增加开窗口、图形等功能,同时也可构 成分布式数据库环境中的网络结点。访问网络中数据库服务器中的数据。这样,我 们不仅实现了ORACLE与DBASE的双向转换,而且能在DBASE环境下执行标准SQL语言所 有DDL、DML和部分DCL语句。使用该方法,原有的DBASE程序和数据库资源能继续使 用,对于需共享的数据,也可以经转换后部分或全部放到服务器上,对于所增加的 功能模块,亦只需在原程序中进行更新即可满足整个系统的使用,因此缩短了开发 周期,节省了硬件投资。 然而,ORACLE版本7已放弃了对DBXL的支持,那么如何实现DBASE或XBASE &127;对 ORACLE7的访问呢?我们通过重写DBXL和ORACLE7数据库的接口,可方便地实现DBASE FOXBASE或FOXPRO数据库对ORACLE7的访问,从而保护了原有应用。 二 实现方法 DBXL支持DBASE语法集和SQL语言。将DBASE应用转换为ORACLE DBXL应用就是将 DBASE格式的数据转换到ORACLE库中。大多数用DBASE编写的应用不用修改即可在 ORACLE DBXL下运行。 将DBASE、XBASE应用连接到ORACLE数据库,在DBASE用程序开始处加入如下行: CONNECT <用户名/口令> 为了编制ORACLE7与FOXBASE进行数据交换的通用接口程序,我们首先建立工作 数据库WORK.DBF,其结构如下: FIELD FIELD NAME TYPE WIDTH DEC 1 KEY N 1 2 NODNAME C 10 3 NFNAME C 10 4 LFNAME C 10 5 COND C 80 6 SUCC L 1 其中:KEY表示操作码,KEY=1表示工作站从服务器上取数据;KEY=2 表示工作站 送数据至服务器;KEY=3表示从服务器删除所有满足条件的记录。NODNAME表示用户 名,NFNAME表示服务器上ORACLE7的表名,LFNAME表示工作站上对应的FOXBASE数 据库名,COND&127;表示条件(=.T.),&127;SUCC=.F.。 下面我们提供了ORACLE7与FOXBASE进行数据交换的程序清单,希望能够起到抛 砖引玉的作用.在实际运行.DO MENU的过程中,只需修改工作站/口令名(NETWORK)和 网络工作站上FOXBASE数据库(GOOD.DBF)名称,以及对应的服务器上ORACLE7表名 (GOOD)即可。 值得注意的是:和ORACLE7进行数据交换的FOXBASE数据库只允许有N、D、C 三种数据类型,如果其中有L、M型的字段,须改为字符型。 MENU.PRG(主控程序): sele a ok=.f. keyword=3 network="cw" &&表示网络工作站用户名 tablnam ="good" &&表示网络工作站上ORACLE7表名 dbfnam ="good" &&表示工作站上对应的FOXBASE数据库名(GOOD.DBF) condit=.t. &&表示FOXBASE的数据库GOOD.DBF全部上网 do exchdbf with keyword,network,tablnam,dbfnam,condit,ok if ok set color to w/n clear do case case keyword=1 set color to gr+/r @8,10 clear to 16,60 @8,10 to 16 , 60 double @12,16 say "从 网 络 服 务 器 上 取 数 据 成 功 !!! " del=inkey(3) case keyword=2 set color to w+/b @8,10 clear to 16,60 @8,10 to 16,60 double @12,16 say " 数 据 上 网 成 功 !!! " del=inkey(3) case keyword=3 set color to bg+/r @8,10 clear to 16,60 @8,10 to 16, 60 double @12,16 say " 从 网 络 服 务 器 上 删 除 数 据 成 功 !!!" del=inkey(3) endcase else return endif ? sys(2002,1) return EXCHDBF.PRG(数据交换程序): para keyword,network,tablnam,dbfnam, condit, ok
use work goto top replace key with keyword nodname with network nfname with ; tablnam lfname with dbfnam cond with condit succ with ok use save screen !foxswap dbxl nettran restore screen use work ok=succ use return NETTRAN.PRG(数据交换程序): set talk off set echo off set menu off set stat off set safe off set autolock on on error do errhand user="aj" &&用户名 pass="aj" &&口令 login=user+"/"+pass connect &login set oracle off set color to gr+/r @10,10 clear to 14,62 @10,10 to 14,62 double @12,13 say "本站与网络服务器正在交换数据 , 请用户稍侯 !!!" sleep (1) select 1 use work automem store automem use tabname=trim(nfname) if key<>2 tabname=trim(nodname)+tabname) endif set oracle on ok=file("&tabname"+".dbf") if .not.ok.and.(key=1.or.key=3) @12,13 say "网络服务器上无 "+"&tabname"+".dbf 数据库" sleep(3) quit endif cond=ltrim((trim(cond))) more=len(cond) do case case key=1 && get file or records from service
if more=0 select * from &tabname save to temp &lfname keep
else select * from &tabname where &cond save to temp &lfname keep endif case key=2 && put file or records to serveice
set oracle off select 1 use &lfname automem select 2 set oracle on if .not.ok select 1 copy struc to &tabname grant select on &tabname to public select 2 endif use &tabname alias luckly select 1 set filter to &cond goto top do while .not.eof() select 2 do test with tabname select 1 skip enddo select 2 use select 1 use case key=3 && delete all records meeting condition delete from &tabname where &cond commit other set color to gr+/r @12,16 say "操作码出错, KEY=1,KEY=2,KEY=3" sleep(4) endcase set oracle off use work ok=.t. replace succ with ok use set color to w/b clear quit ERRHAND.PRG(出错处理程序): set talk off set echo off set stat off set menu off store error() to errnum do case case errnum=108.or.errnum=109 do while .t. set colo to w/n clear set colo to gr+/r @10,20 clear to 14,60 @10,20 to 14,60 double y=" " @11,22 say "文件或记录被其他用户使用 " @12,22 say "通知其他用户暂时退出 " @13,22 say "按回车键继续重试" get y read if y=" " retry endif enddo case errnum=1 set colo to w/n clear set colo to w/r @10,20 clear to 14,60 @10,20 to 14,60 double @11,22 say "文 件 不 存 在 请 建 立 文 件 !!!" @13,22 say "按退出,按其它键继续 " wait"" on esca return retry case errnum=26.or.errnum=20 set colo to w/n clear set colo to w/r @10,20 clear to 14,60 @10,20 to 14,60 double @ 11 ,22 say " 数据库记录没索引 !!!" @13,22 say "按退出,按其它键继续 " wait"" on esca return retry case errnum=148 set colo to w/n clear set colo to w/r @10,20 clear to 14,60 @10,20 to 14,60 double @ 11,22 say " 网 络 服 务 器 忙" @13,22 say "按退出,按其它键继续 " wait "" on esca return retry case errnum=139 set color to w/n clear set color to gr+/r+ @9,9 to 15,61 double set color to gr/r+ @10,10 clear to 14,60 set color to gr+/r+ @12,16 say "联网络服务器不成功,暂时不能查询" sleep(10) quit endcase return TEST.PRG(数据交换子程序): parameter table_name set cons on set echo off set oracle on select 2 alias_name=alias() go bottom record_no=recno()+1 use select 1 r=recno() set oracle off copy structure to temp1 extended select 2 use temp1 go top fd="insert into "+table_name+" (recno) values ("+ltrim(str(record_no))+")" &fd commit set oracle on i=1 do while .not. eof() f_name=trim(field_name) update_f="update "+table_name+" set "+f_name+"="
update_s=" " app="f_name" do case case field_type="N" select 1 update_s=update_s+ltrim(str(&f_name)) case field_type="C" select 1 update_s=update_s+"'"+ltrim(trim(&f_name))+"'"
update_s=f_name endif case field_type="D" select 1 dvalue=dtoc(&f_name) subs=substr(dvalue,4,2) if len(trim(subs))=0 select 2 skip loop endif do case case subs="01" months="jan" case subs="02" months="feb" case subs="03" months="mar" case subs="04" months="apr" case subs="05" months="may" case subs="06" months="jun" case subs="07" months="jul" case subs="08" months="aug" case subs="09" months="sep" case subs="10" months="oct" case subs="11" months="nov" case subs="12" months="dec" endcase date_s=substr(dvalue,1,2)+"-"+months+"-"+substr(dvalue,7,2) update_s=update_s+"'"+date_s+"'" case field_type="M" copy file mem.dbt to mem_1.dbt select 2 skip loop endcase update_b=" where recno="+ltrim(str(record_no))
&update_f; &update_s; &update_b select 2 skip enddo commit select 2 use set oracle off delete file c:dbxl emp1.dbf set oracle on use &table_name alias &alias_name return 以上程序在服务器为SCO UNIX SYSTEM RELEASE3.2 V4.2.1操作系统,&127;ORACLE RELEASE7.1.4 FOR SCO UNIX数据库;工作站为MFOXPLUS2.1 FOR DOS,FTP PC/TCP V2.03,SQLNET WITH TCP/TP 的环境下通过。
| |
|
|
| |
| |
|