数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
[UDF系列]如何创建InterBase UDF

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

[UDF系列之五]:如何创建InterBase UDF

by Paul McGee (c) Borland Internation Inc.

Warton


[概述]:

用户定义函数(UDF)是一种采用编译语言编写的函数,是用户为执行自定义的功能和常用的任务面设计的。UDF 允许程序员模块化一个数据库应用程序,并能嵌入到数据库以增强数据库自身的功能。UDF 也总是在数据库服务器端执行。这可以减少网络通信量。

UDF可以执行事务比如获得服务器上可用硬盘空间,清理字符串的空格,为一系列值计算标准偏差等等。UDF能完成任何功能只要编程语言能够表达出来。这种编程语言能常是在C和C++之间选择(当然,用户可以用其它语言,比如pascal 译者注)。

UDF在提供SQL语言不能处理的功能、查询、更新数据库,以及为异源客户工作站提供通用函数方面非常有效。

与其它功能相比,使用UDF要花费一些代价。这主要表现在两方面:第一,在UNIX或VMS平台,UDF是模块化AST程序,这意谓着当UDF在执行时,没有其它的存取操作可以发生。这就要求我们尽量使UDF尽可能的小和有效率。第二,如果数据库服务器崩溃,你需要将数据转移到另一台机器上。你必须首先在新的服务器上安装UDF。如果在相同的操作系统下,这并不难。但是当转移到另一操作系统时,你只少需要编译一遍UDF库的源代码。

[UDF示例]:

     InterBase包含几个内置SQL 函数:UPPER,GEN_ID,CAST 。UPPER将一个字符串转为大写。GEN_ID生成一个唯一长整型值,因为一个特殊的生成器已经在数据库中定义。这在生成主键时是非常有用的,比如客户编号或职员编号。CAST将一种类型列转化为另一种类型的列。

    InterBase 也提供了另外一些UDF的源代码,在examples目录下。它们包含在udflib.c文件中。这里定义的UDF有:lower, strcat, substr, trim, trunc, doy, moy, dow, sysdate, add2, mul, fact, abs, maxnum, sqrt, blob_linecount, blob_bytecount, substr_blob。Lower是将字符串转化为小写串。Strcat连接两个字符串。Substr返回字符串的一部分。Trim清空字符串中的空格。Trunc返回删节后的串。doy(day of year),moy(month of year),dow(day of week)。Sysdate返回当前日期以字符串的形式(“mmm-dd-yyyy”).add2将两整数相加在一起。Mul将两double数相乘.maxnum返回两数中较大者。Sqrt为取平方。blob_bytecount返回blob的大小。Substr_blob,取blob的一部分文本。

    我们将增加几个新的UDF:rtrim, left, right, swapcase, imonth, iday, iyear。Rtrim去掉字符串右边的空格。Left返回一个输入串前n个字符的串。Right则是返回右过n个字符的串。Swapcase将小写转大写并将大写转小写。imonth返回月份的值(1-12)。Iday返回day的值(1-31)。Iyear返回年的值如:2002。

[编写UDF]:

    一旦你编写的UDF,你必须创建一个动态链接库,以便上UDF可以使用。然后你必须在数据库中定义它。

在数据定义语言中定义 UDFs 非常简单,基本的语法是:

DEFINE EXTERNAL FUNCTION name [<datatype> | CSTRING (int)

                [, <datatype> | CSTRING (int) ...]]

                RETURNS {<datatype> [BY VALUE] | CSTRING (int)}

                ENTRY_POINT "<entryname>"

                MODULE_NAME "<modulename>" ;

Name是指函数的名称,它可达到31个字符长。第一个datatype是输入参数。Datatype指标准的interbase数据类型:INTEGER, CHAR, VARCHAR等。或者,你可以使用CSTRING这个C风格没用结束的字符数组。Entry_point指实际的函数名。在InterBase提供示例中,SQL函数名是lower而实际函数名在udflib.c中为fn_lower_c。模块名指的是函数被编译后的输出库名。例如:这里用SQL 定义函数lower和substr。

        DEFINE EXTERNAL FUNCTION lower

                VARCHAR (256)

                RETURNS CSTRING (80)

                ENTRY_POINT "fn_lower_c" MODULE_NAME "funclib";

       

        DEFINE EXTERNAL FUNCTION substr

                CSTRING (256), SMALLINT, SMALLINT

                RETURNS CSTRING (80)

                ENTRY_POINT "fn_substr" MODULE_NAME "funclib";

为了将函数加入到函数库中,在NT上使用Borland C++,我们应该让lib模块有有一个本地的拷贝:

 implib mygds32.lib \interbas\bin\gds32.dll

然后连接必要的选项生成我们新的库funclib.dll。

 

bcc32 -v -a4 -DWIN32 -tWM -tWCD -efunclib.dll udf.c mygds32.lib

为了在本地使用DLL,它必须在BIN目录下(或你环境变的路径中)。如果要在远程使用,它必须在能运行InterBase服务的用户的环境变量路径之中,默认情况下,它在系统账户的PATH中。

[使用UDF]:

一但编译,连接,定义之后,一个UDF就可以在SQL 语句中使用了。

它们可以做如下使用:定义计算后字段做为表定义的一部分,在view定义中中做为列表达式或在存储过程和触发器中做为SELECT, INSERT, UPDATE, DELETE操作的一部分。

例如,使用计算结果做为字段:

        CREATE TABLE name ( FIRST_NAME VARCHAR(20), LAST_NAME VARCHAR(20),

                FULL_NAME_UPPER COMPUTED BY

                (upper(FIRST_NAME) | " " | upper(LAST_NAME)));

view中做为一个列表达式:

        CREATE VIEW upper_names (FIRST_NAME, LAST_NAME) AS

                SELECT upper(n.first_name), upper(n.last_name) FROM name n;

在选择操作中:

        SELECT substr(n.FIRST_NAME, 2, 4) FROM name n WHERE

                upper(n.LAST_NAME) = 'MOORE';

在插入操作中:

        INSERT INTO name (FIRST_NAME, LAST_NAME)

                VALUES (rtrim(:new_fname), rtrim(:new_lname));

在更新操作中:

        UPDATE name SET LAST_NAME = rtrim(:new_lname) WHERE

                upper(n.LAST_NAME) = 'JONES';

在删除操作中:

        DELETE FROM name WHERE left(LAST_NAME, 3) = 'SMI';

 

 

本主来自:MER Systems Inc..  http://www.mers.com

 




相关文章

相关软件