在Developer/2000中调用VB
Oracle数据库管理系统是优秀的数据库管理系统,其开发工具Dev
eloper/2000也是一个功能强大、方便灵活的工具软件,许多Oracle数据库开发人员都选择Developer/2000作为系统开发工具。但当今的数据库用户已不局限于枯燥无味的数据,他们希望以图文并茂的方式显示查询结果。因此在设计项目时,一般是选择Developer/2000来开发有关数据库的维护功能,而选择其它如VB、VC等优秀的程序语言来开发有关图形等方面的工作。这就带来一个问题:如何实现Oracle与它们的连接。本文就Oracle与VB5.0的连接来谈一点自己的体会。
VB5.0与Oracle数据库的连接
VB5.0可以与多种外部数据库连接,比如从Microsoft Access、dB ASE、Microsoft Excel、FoxPro、Lotus、Paradox等数据库中读取数据;通过ODBC,VB5.0可以与SQL
Serve r和Oracle相连。通过ODBC连接数据库时,首先要正确配置ODBC的DSN(Data Source Name
,即数据源) ,然后在VB5.0中通过Data控件或RDO对象连接数据库。
1. 配置ODBC
在Windows 95的控制面板中用鼠标双击32bit ODBC,启动ODBC数据源管理器(ODBC Data Source
Administrator)。在"UserDSN"方式下按"Add"按钮,出现"Create
New Data Source"对话框,从中选择"M icrosoft ODBC Driver for
Oracle"(该驱动在VB安装时自动安装;或在VB安装时选择"Custom"方式,在Data
Access选项中选择"Oracle OD BC Driv er"),按下"Finish"按钮。此时出现"Microsoft
ODBC Drive r for Oracle Setup" 对话框,在"Data Source Name"中给定一名称(
如my_dsn),在"User Name"中写上在Oracle数据库中的用户名(如scot t),在"Connect
String"中写上想要连接的Oracle数据库别名(该别名登记在tnsnames.ora文件中,可以通过手工编辑该文件或通过Develop
er/2000中的工具"SQL Net Easy Configuration"来配置)。
2. 设置Data控件
Data 控件非常简单易用,可以用来执行大部分数据访问操作,而根本不用编写代码。一个Data 控件可以对应一个基表或视图(可以是数据库中固有的视图对象,也可以是在RecordSource属性中的SQL
SEL ECT语句所选出的数据集合)。启动VB,在Form上添加Data控件(如Data 1),并设置其Connect属性。Connect
属性中记载着连接字符串,它可以由多个参数组成:
·DSN:用户名称注册ODBC数据源;
·UID:数据库的一个可识别的用户名;
·PWD:与用户名相关的密码。
例如将Connect属性置为"ODBC;DSN=my_dsn;UID=scott;PWD=tige r",然后从RecordS
ource属性的列表框中选择某一基表或视图。
Data 控件可以与DBList、DBCombo、DBGrid 和 MSFlexGrid字段结合使用,只要将它们的DataSource属性设置为某一控件(如Data1)即可,详见VB的有关手册。
关于VB与远程数据库的连接,请参阅《计算机世界》1998年4月20 日的"VB5.0中远程数据库的访问"及1998年5月25日的"用VB和RDO访问
SQL Server",此处不再赘述。
从Developer/2000向VB应用程序传递参数
Developer/2000调用VB应用程序可以有两种方式:一是通过HOST 过程调用外部命令(VB应用程序),如HOST("notepad.exe");二是通过D
DE包来调用VB应用程序,如:
DECLARE
AppID PLS_INTEGER;
BEGIN
AppID:= DDE.APP_BEGIN(‘notepad.exe’);
END;
下面主要介绍从Developer/2000向VB应用程序的参数传递。
1. 命令行参数
我们知道,C语言中是通过int main(int argc[, char*argv[ ] [ , char*envp[
] ] ]) 来接收命令行参数的,但在VB中没有对应的语法。好在VB提供了COMMAND()函数来返回命令行参数,以下函数可以分解命令行参数并返回参数数组:Function
GetCommandLin e(Optional MaxArgs)
Dim C, CmdLine, CmdLnLen, InArg, I, NumArgs
'检查是否提供了 MaxArgs 参数。
If IsMissing(MaxArgs) Then MaxArgs = 10
ReDim ArgArray(MaxArgs) As String
NumArgs=0: InArg = False
CmdLine=Command()
CmdLnLen=Len(CmdLine)
'以一次一个字符的方式取出命令行参数。
For I=1 To CmdLnLen
C=Mid(CmdLine, I, 1)
If (C<>" " And C<> vbTab) Then
If Not InArg Then
If NumArgs = MaxArgs Then Exit For
NumArgs = NumArgs+1
InArg = True
End If
’将字符加到当前参数中。
ArgArray(NumArgs) = ArgArray(NumArgs)+C
Else
InArg=False
End If
Next I
ReDim Preserve ArgArray(NumArgs)
GetCommandLine = ArgArray()End Function
调用方式如下:
Dim cmdarray As Variant
Rem cmdarray=GetCommandLine()
这样,从Developer/2000中调用用VB编写的应用程序时就可以向它传递参数,如:
AppID:=DDE.APP_BEGIN(‘notepad.exe myfile');
注意:在退出Developer/2000之前一定要先终止所调用的程序,如 DDE.APP_END(AppI D)。
2. 用基表或视图来传递参数
当要传递大量的数据时,上述方法就行不通了。例如,将在Develo per/2000中从数据库某个基表中查询出的记录集合传给VB以进行图形显示。解决这一问题的通常方法是将数据全部写入文件(Oracle
Deve loper/2000提供了内建软件包TEXT_IO来进行文件操作),然后以文件名为参数调用VB应用程序。但采用这种方法时,VB应用程序对数据进行检索和排序比较困难,而且文件操作本身也比较烦琐,数据量大时,
速度问题比较突出。
一种好的解决方法是用数据库作为传递参数的中介,利用基表或视图来保存检索出的数据,然后只要向VB应用程序传递基表或视图名即可,而VB的强大的数据库功能可以得心应手地操纵数据。但是Oracl
e的PL/SQL只支持DML(Data Manipulation Language,即数据操作语言 ),而不支持DDL(Data
Definition Language,即数据描述语言),因此在PL/SQL中不能动态产生基表或视图。好在Oracle数据库中提供了DB
MS_SQL包,该包可执行任何DDL 或DML,包括创建或删除基表及视图。
下例是在Developer/2000 FORMS中根据当前块的默认选择条件创建一视图:DECLARE
cursor_name
INTEGER;
rows_processed INTEGER;
table_name
VARCHAR2(20):=get_block_property
(:system.cursor_block, base_table);
wh_string
VARCHAR2(500):=Rtrim
(get_block_property (:system.cursor_block,default_where) );
sql_string VARCHAR2(400);BEGIN
:globe.view_name:= ‘v_’|| table_name;
sql_string := ‘create view ’||:globe.view_name ||
‘as select*from ’|| table_name;
If wh_string Is Not Null Then
sql_string := sql_string || ‘where'|| wh_string;
End If;
cursor_name := dbms_sql.open_cursor;
dbms_sql.parse(cursor_name,sql_string, dbms_sql.v7);
rows_processed := dbms_sql.execute(cursor_name);
dbms_sql.close_cursor(cursor_name);END;
上例中,open_cursor获得一个新的游标(cursor)号, parse对所要执行的语句进行语法分析, execute执行给定的游标,close_cursor
关闭游标、释放内存。
DBMS_SQL包还有其它许多功能(如将值绑定给SQL语句中的变量、读取查询结果等), 有兴趣的读者可以查阅Oracle手册Oracle
Server Application Developer's Guide。
Developer/2000与VB应用程序的统一
用Developer/2000开发的应用程序在执行时会出现一个MDI窗口, 应用程序中的所有窗口都在此MDI窗口之内;而用VB开发的应用程序拥有自己独立的窗口,这样开发出的应用软件会给用户以两个平台、两套系统之嫌。如果能够解决这个问题,就会使应用软件系统增色不少。我们很自然地想到将VB的Form(窗口)的父窗口设成Develop
2000的 MDI窗口。
1. 获得Developer/2000的MDI窗口句柄
Developer/2000 FORMS用FORMS_MDI_WINDOW标记FORMS的MDI窗口 ,用get_window_pr
operty获得其窗口句柄后就可以将它作为参数传给VB应用程序。DECLARE
w_hdl BINARY_INTEGER;BEGIN
w_hdl:=TO_NUMBER(get_window_proper (FORMS_MDI_WINDOW, WINDOW_HANDLE))
AppID := DDE.APP_BEGIN(‘My_app.exe'|| :
globe.view_name || ‘ ' || TO_CHAR(w_hdl));END;
2. 将VB的窗口(Form)放入Developer/2000的MDI窗口
VB调用Windows API非常简单,只要在调用之前对所调函数进行说明即可。格式说明可以使用VB的工具API Text
Viewer。运行API Tex t Viewer,装载Win32api.MDB,从中选出所需的API函数,增加到"Selec
ted Items"框内,再拷贝到剪贴板,然后粘贴到VB的说明部分即可。示例如下:Private Declare
Function SetParent Lib "user32" (ByVa l hW ndChild As
Long, ByVal hWndNewParent As Long) As LongPr ivate Sub Form_Load()
Dim cmdarray As Variant
cmdarray = GetCommandLine()
rc = SetParent(Me.hWnd, cmdarray(2))
Data1.Connect = "ODBC;DSN=my_dsn;UID=
scott;PWD=tiger"
Data1.RecordSource = "scott." + cmdarray(1)End Sub
将该VB应用程序编译成可执行程序,以便Developer/2000调用。
至此,VB的窗口已经纳入Developer/2000的MDI窗口内。我们可以将VB Form的ShowI nTaskbar属性设置成False,使VB应用程序不出现在任务栏内,同时给该Form的Icon属性赋一个与Developer/2000窗口图标相似的图标,这样用户几乎分辨出软件哪一部分是用Dev
eloper/ 2000开发的,哪一部分是用Visual Basic开发的。
国家基础地理信息中心 王小平