CSDN博客

img nthb2001

在Adaptive Server Anywhere和Oracle之间构造通用函数

发表于2001/7/6 11:19:00  690人阅读

在Adaptive Server Anywhere和Oracle之间构造通用函数


辽河油田锦采地质大队 邓先永
01-7-2 上午 10:29:41


在使用PowerBuilder编制程序时,使用的最多的数据库接口是它自身集成的Adaptive Server Anywhere和大型数据库管理系统Oracle;有时,为了使程序的运行、移植更加方便,比如从服务器的数据管理端立即转到单机的数据管理端时,往往涉及到用户在程序的SQL语句中所使用的不同数据库平台上,函数的兼容性问题。
比如在最后的数据汇总时,为了保证计算结果的正确性,就要使用防止空值发生的函数,这个函数在Oracle中是nvl(x,y);用法为:
select name,nvl(age,”年龄未知”) age,nvl(zipcode,”无邮政编码”) zipcode from unknow_personal;
则可能出现的结果为:
name age zipcode
张三 45   无邮政编码
李四  年龄未知   234567
王五  年龄未知 无邮政编码
而在Adaptive Server Anywhere的单机数据库平台上,就要用isnull等函数了,语法为:
select name,isnull(age,”年龄未知”) age,isnull(zipcode,”无邮政编码”) zipcode from unknow_personal;
最后的结果是一样的。
现在问题是当我们所用的数据库要从Oracle移植到单机版的Adaptive Server Anywhere上时,由于某些函数的不通用性,程序就要修改相应的函数调用,重新编译,如果在程序中大量或多处使用这种函数时,就很有可能导致人为的错误,从而使程序的维护工作量加大,我曾在网上发过有相关帮助的帖子,但不太切中要害。经过仔细研究一段时间后,终于在Adaptive Server Anywhere单机平台上实现了Oracle上的函数nvl(),使我的程序应用更加方便,现写下来与大家共享。
另外,本人以前用PB6的时候,在PB6的Database Administrater Painter中曾编写过比较复杂的Stored Procedure,但是由于PB6中在处理和Database直接接口的Script时,对于” ; ”和” ’ ”的使用上较多的不方便之处,因而实现时花费了不少的气力,虽然在PB7中此毛病仍然存在,但在PB7的光盘中集成的Adaptive Server Anywhere 6.0的管理工具却比在PB6中的优秀很多,使用Manager Adaptive Server Anywhere这个工具就能很轻松地对数据库进行操作。
首先,如果大家已经正确安装了PB7.0.1后,就可以通过以下步骤来启动Manager Adaptive Server Anywhere:开始→Sybase→Manager Adaptive Server Anywhere。
启动后出现管理界面,再按如下步骤:选菜单Tools→Connect→Adaptive Server Anywhere,再选择你在系统ODBC中配置好的数据源(PB7.0.1对此处理比较好,把各种数据源都集成到系统的ODBC配置中来进行,比较正规,可能初学者还不太适应吧!),如果有必要,可以在User ID:和Password:处输入连接数据库的用户名和口令,之后按确定,就进行数据库的连接。
比如我们此次连接ASA 6.0 Sample,当然用户在实际应用中就要连接自己的数据库了,如果连接成功,会在Sybase Central下的Adaptive Server Anywhere下出现asademo的图标了;双击鼠标,打开asademo;再双击asademo(dba),打开其下的Tables,Views,Procedures&Functions
等子项,单击rocedures&Functions
项,在右边窗口中就会出现当前连接的数据库中所支持的过程和函数,在右边窗口中双击Add Function (Template),此时会出现New Function的窗口,窗口中有一个函数的大致框架,但为了实现在Oracle中的nvl()函数,请将New Function窗口中的语句改为如下的形式:
create function nvl(in x text,in y text)
returns text
begin
declare z text;
if x is null then
set z=y
else
set z=x
end if;
return(z)
end
为了以上几行Script,本人也试过多次才成功,首先是上面的(in x text,in y text),表示函数有两个输入参数:x,y,而数据类型是text。这个text数据类型真是很有趣,我想就算是Sybase公司很好的创意吧!刚开始时,我用的是real类型,但它处理数值型字段时可以,但在处理字符型的字段时就不灵了,后来又仔细分析了一下Adaptive Server Anywhere所提供的数据类型后,改用text一切才OK!后面的Script,我曾想直接调用Adaptive Server Anywhere的isnull()函数,却没有成功,欢迎广大网友积极参与讨论;至于其它的Script,大家仔细看看Adaptive Server Anywhere的帮助后,应该是可以写出来的。
之后,选择New Function窗口的File→Excute Script执行此语句,就行了,这时回到Manager Adaptive Server Anywhere的管理界面,在Procedures&Functions项中,就会有nvl()函数了,用它即可参与实战。
下来还有一步,本来这一步可有可无,因为在数据库只要有了nvl()的定义后,就可以在PB中直接写带有nvl()的Script,而不会出现语法错误了,但是,为了用户能在PB中直接调用,就算是形成一个完整的应用,建议大家还是坚持完成下面的过程,反正又不太费劲,另外还可以长知识呢。
大家在构建DataWindow的时候,相信已经使用过相应数据库中的函数,特别是在用计算列时,就很有可能用到函数了,现在,我们要把在Adaptive Server Anywhere中实现的类似于Oracle的nvl()函数,让它出现在DataWindow Painter的可以直接选取的函数名中(本来用Oracle连库是有的,但用Adaptive Server Anywhere连库时就会有isnull()函数可选,而没有nvl()可选),经过我们的分析,可以用以下几步来实现:
1.找到Sybase安装目录的/Shared/PowerBuilder下的pbodb70.ini文件,打开它,找到[Adaptive Server Anywhere],可以看到PBFunctions='ASA_FUNCTIONS',即Adaptive Server Anywhere数据库所用的函数是从ASA_FUNCTIONS处来获得,只要我们把关于nvl()的声明放到ASA_FUNCTIONS的相应部分,就可以在Adaptive Server Anywhere 数据库中,在PB的开发界面中,直接使用nvl()函数了(由此可见在PB中ini文件的重要性)。
2.在pbodb70.ini文件中找到Functions段的[ASA_FUNCTIONS],在Functions=abs(x)…的合适的地方加入关于nvl()的声明:”nvl(x,y),”(建议加到ifnull(x,y,z),处)即可。存盘退出,之后启动PB,大家就可以看到,即使使用Adaptive Server Anywhere 数据库,也一样可以使用Oracle中的nvl()函数了。
这样有一个比较重大的意义是:实现了这样的函数后,用户的程序就可以在服务器版和单机版间通用了,省去了为服务器版和单机版分别开发不同代码的麻烦;一旦在单机数据库上建立好同服务器相同的库结构,装载相似的数据后,就可以同等使用。
以上是本人日常开发的经验所得,错误和不足疏漏之处再所难免,本文旨在抛砖引玉,关于数据库开发工具PowerBuilder的使用,且就本文上述的各个方面,确有许多可以大开论坛,讨论一番的必要,欢迎广大PB,VC开发者与我联系hard_deng@netease.com。
2000年6月9日
另外我还在又造了其它的几个函数:即在sqlanywhere下生成的ceil、add_months和to_char函数:
create function ceil(in x real)
returns integer
begin
declare z integer;
set z=ceiling(x);
return(z)
end
create function add_months(in x date,in y integer)
returns date
begin
declare z date;
set z=months(x,y);
return(z)
end
create function to_char(in x date,in y TEXT)
returns TEXT
begin
declare z TEXT;
declare ii integer;
if y='yyyymm' then
set ii=112
end if;
set z=convert(char(8),x,ii);
set z="left"(z,6);
return(z)
end
0 0

相关博文

我的热门文章

img
取 消
img