摘要:本文提供了在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 co 查看本文来源