打印本文 打印本文 关闭窗口 关闭窗口
在Adaptive Server Anywhere和Oracle之间构造通用函数
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1246  更新时间:2009/4/22 22:10:43  文章录入:mintao  责任编辑:mintao

在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

打印本文 打印本文 关闭窗口 关闭窗口