[UDF系列]如何编写InterBase UDF 之二

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

(接上一篇)

如何编写InterBase UDF

warton

怎么编写字符串和日期型处理函数的UDF呢?

 

下面编写一个“Left“函数

    内存分配问题:

              如果你使用IB(InterBase)5.1以下版本的话,在你的单元文件中键入下面的声明:

function malloc(Bytes: Integer): Pointer; cdecl; external 'msvcrt.dll';

       如果你有5.5以上的版本,你就不需要这么做了。这样,先确定ib_util.pas 文件在你的编译器可以找到的路径中,并且ib_util.dll也在你的搜索路径之中。

最简单的方法是放到的库可搜索到的路径。

                            c:/Program Files/InterBase Corp/InterBase/include

然后复制

              c:/Program Files/InterBase Corp/InterBase/lib/ib_util.dll

        到你的windows系统目录下(典型的是:c:/Windows/System)。最后在你的单元文件的use子句中将ib_util.pas加进去

                uses

               ...,

ib_util;

为什么有如此奇特的内存分配?为什么我不能用AllocMem分配内存,或者其它方法?问题很简单:你不能,所以不要问!更复杂的问题是每一个编译器使用它喜欢的算法来进行内存管理,这是被操作系统控制着的。例如,VC和Delphi管理内存的方式不同,猜这是为什么?IB是在VC下编译的,在5.5以前的版本中,你必须直接指定运行库。在IB5.5之后,IB给了一个IB调用使得这成为可能。既然这样,那我们继续进行编写字符串操作的函数。

 

构建函数

       在新的单元文件中,作如下声明:

function Left(sz: PChar; Cnt: Integer): PChar; cdecl; export;

    在函数实现部分:

               (* Return the Cnt leftmost characters of sz *)
function Left(sz: PChar; var Cnt: Integer): PChar;
var
  i: Integer;
begin
  if (sz = nil) then
    result := nil
  else begin
    i := 0;
    while ((sz[i] <> #0) and (i < cnt)) do Inc(i);
    result := ib_util_malloc(i+1);
    Move(sz[0], result[0], i);
    result[i] := #0;
  end;
end;

 

在你的工程文件中,在“exports“部分键入:

               exports
               Modulo,
               Left;
 

Now,再次编译工程项目….

现在,为了使用函数,在ISQL中重新连接数据库,输入:

                declare external function f_Left

               cstring(64), integer

               returns cstring(64) free_it

entry_point 'Left' module_name 'dll name minus ".dll"';

测试这个函...

select f_Left('Hello', 3) from rdb$database

 

仍然相当简单,哈?

 

上我们来编写一个时间函数

 

       IB6中,有三种不同的时期类型被支持,DATE,TIME,TIMESTAMP,与IB5.5及以前老版本中的相比,TIMESTAMP 的数据类型实质上相当于IB5.5DATE类型。

       为了在你的程序中”decode””encode”这些类型。你应该了解一点IB API相关的信息。输入以下代码:

interface
...
 
type
 
  TM = record
    tm_sec : integer;   // Seconds
    tm_min : integer;   // Minutes
    tm_hour : integer;  // Hour (0--23)
    tm_mday : integer;  // Day of month (1--31)
    tm_mon : integer;   // Month (0--11)
    tm_year : integer;  // Year (calendar year minus 1900)
    tm_wday : integer;  // Weekday (0--6) Sunday = 0)
    tm_yday : integer;  // Day of year (0--365)
    tm_isdst : integer; // 0 if daylight savings time is not in effect)
  end;
 
  PTM             = ^TM;
 
  ISC_TIMESTAMP = record
    timestamp_date : Long;
    timestamp_time : ULong;
  end;
 
  PISC_TIMESTAMP = ^ISC_TIMESTAMP;
 
implementation
...
 
procedure isc_encode_timestamp  (tm_date: PTM;
                                                            ib_date: PISC_TIMESTAMP);
                                stdcall; external IBASE_DLL;
 
procedure isc_decode_timestamp  (ib_date: PISC_TIMESTAMP;
                                 tm_date: PTM);
                                stdcall; external IBASE_DLL;
 
 
procedure isc_decode_sql_date   (var ib_date: Long;
                                 tm_date: PTM);
                                stdcall; external IBASE_DLL;
 
procedure isc_encode_sql_date   (tm_date: PTM;
                                 var ib_date: Long);
                                stdcall; external IBASE_DLL;
 
 
 
procedure isc_decode_sql_time   (var ib_date: ULong;
                                 tm_date: PTM);
                                stdcall; external IBASE_DLL;
 
procedure isc_encode_sql_time   (tm_date: PTM;
                                 var ib_date: ULong);
                                stdcall; external IBASE_DLL;

现在我们写日期UDF:

       在单元文件的interface部分,输入声明:

function Year(var ib_date: Long): Integer; cdecl; export;
function Hour(var ib_time: ULong): Integer; cdecl; export;

implementation(实现)部分,输入:

function Year(var ib_date: Long): Integer;
var
  tm_date: TM;
begin
  isc_decode_sql_date(@ib_date, @tm_date);
  result := tm_date.tm_year + 1900;
end;
 
function Hour(var ib_time: ULong): Integer;
var
  tm_date: TM;
begin
  isc_decode_sql_time(@ib_time, @tm_date);
  result := tm_date.tm_hour;
end;

最好,在你的工程文件中:在““部分,输入:

exports

Modulo,

Left,

Year,

Hour;

现在编译工程...

 

为了使用这个函数,就像上面那样:用ISQL连接数据库,输入:

declare external function f_Year
date
returns integer by value
entry_point 'Year' module_name 'dll name minus ".dll"';
 
declare external function f_Hour
time
returns integer by value
entry_point 'Hour' module_name 'dll name minus ".dll"';

最后再测试一下看!

select f_Year(cast('7/11/00' as date)) from rdb$database

这一部分并非像前面字符串和整数那样操作哪样了,但是还是相当...simple,哼!

编写Linux/Unix平台的UDF

(未完待续!!)

Delphi数据库访问组件IBDAC实战:Firebird/InterBase原生连接与性能优化 数据库访问组件是Delphi开发中的关键环节,传统中间层如BDE、ADO、dbExpress在性能、兼容性和部署方面存在诸多痛点。原生连接技术通过直接调用数据库客户端API,绕过冗余中间层,能显著提升数据交互效率与稳定性。IBDAC作为专为InterBase和Firebird设计的组件库,全面支持Delphi 6至13,具备轻量部署、低学习成本和持续更新等优势,广泛应用于存量系统改造、ERP进销存、移动端数据同步等场景。本文围绕IBDAC v9.0.0的安装部署、核心组件使用、事务控制、字符集处理、大数据量 阅读详情

相关推荐

使用VS2019编译fluent2021的UDF程序

记录一下学习使用VS2019完成fluent的UDF程序编译的过程。

qq_67311819的博客 5027

[UDF系列]如何编写InterBase UDF 之三

<!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--><script type="text/javascript"

zgqtxwd的专栏 435

[UDF系列]如何编写InterBase UDF 之一

如何编写InterBase UDF(作者:Gregory Deatz - Hoagland, Longo, Moran, Dunst & Doukas)warton 译 译者叙:由于InterBase性能方面表现突出,并且它是开源和跨平台的,有很多使用Delphi,C++Builder的程序员开始采用它做为其后数据库平台。但是InterBase的中文资料简直太少了。昨日,一网友

知而后定 1507

[UDF系列]如何编写InterBase UDF

译者叙: 由于InterBase性能方面表现突出,并且它是开源和跨平台的,有很多使用Delphi,C++Builder的程序员开始采用它做为其后数据库平台。但是InterBase的中文资料简直太少了。昨日,一网友在CSDN上提到InterBaseUDF(user defined functions 用户自定义函数),我顺手一查,网上竟然查不到这方面的中文资料。于是,我今天将一篇如何编写和使用I

SeekMyself的专栏 2254

[UDF系列]如何创建InterBase UDF

[UDF系列之五]:如何创建InterBase UDFby Paul McGee (c) Borland Internation Inc.Warton译[概述]:用户定义函数(UDF)是一种采用编译语言编写的函数,是用户为执行自定义的功能和常用的任务面设计的。UDF 允许程序员模块化一个数据库应用程序,并能嵌入到数据库以增强数据库自身的功能。UDF 也总是在数据库服务器

知而后定 1700

Write Udf For Interbase/Firebird

DECLARE EXTERNAL FUNCTION IBPASSWDCSTRING(8) CHARACTER SET WIN1252RETURNS CSTRING(16) CHARACTER SET WIN1252 FREE_ITENTRY_POINT IBPasswd MODULE_NAME pibudf.dll;DECLARE EXTERNAL FUNCTI

viocal的专栏 694

Interbase/Firebird Date&Time Function For UDF

type  TIBDate = Integer;  TIBTime = Longword;  TIBTimeStamp = packed record    Date: TIBDate;    Time: TIBTime;  end;procedure IBDecodeDate(IBDate: TIBDate; var Year, Month, Day: SmallInt);var  Centur

viocal的专栏 1279

SocketConnection的使用+interbase精要

笔记:1、InterBase Manager     管理InterBase的服务停止和运行    包括InterBase启动方式,根路径,服务器属性和监控属性2、IBConsole数据库管理工具    集成化、图形用户界面的数据库管理工具3、数据复制IBReplicator (可选部件)4、InterBase 常用数据库设计管理工具    IBConsole 自带    EMS QuickD

专栏 2555

2021 年使用 InterBase 关系数据库进行数据存储和管理的五个理由

在关系数据库领域,InterBase®是一种数据存储和管理解决方案,可提供很多功能。 从顶级安全功能和超级简单的管理到极低的总拥有成本,InterBase 可以保护您的数据、钱包和业务的可持续性。 前瞻性创新:InterBase 的根源 InterBase 最初创建于 1980 年代初,在 Borland旗 下被行业主流采用和进一步开发。在此过程中,它设定了衡量其他数据库性能的标准。 从一开始就被设计成轻量级和可扩展的,这是 InterBase 能够将其强大的引擎扩展到在各种硬件上运行的...

Delphi开发局QQ群:32422310 1330

Firebird/InterBase内置函数使用说明

加*号为FB2.0加入的函数1. COUNT, AVG, MAX, MIN, SUM说明:通用统计函数,不详细介绍了2. EXTRACT(timestamp_part FROM value)说明:EXTRACT(YEAR/MONTHE/DAY/WEEKDAY FROM 字段名)从日期型字段中分离出年,月,日及一个星期的第几天3. CAST(value AS datatype)说明:转换数...

319

C/C++ 连接使用嵌入式数据库 InterBase / Firebird

嵌入式数据库与非嵌入式数据库的差别,在于运行模式的差别。并不是运行在嵌入式手持设备上的数据库就是嵌入式数据库,那种数据库我们通常称做嵌入式移动数据库。理论上讲,嵌入式设备一样可以运行网络数据库的服务端程序。 从这个意义上讲,似乎所有单机数据库都可以算嵌入式数据库,比如Access,Paradox,DBF等等,因为它们都不用启动数据库服务器即可使用。然而,我们通常不将上...

tan_kaishuai的专栏 1609

用Delphi 开发数据库程序经验三则

1.建立临时表  数据输入是开发数据库程序的必然环节。在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,这就需要在本地(客户端)建立临时数据表来存储用户输入的数据,待提交后,清除本地表数据。这种方法的好处是:提高输入效率,减小网络负担。  由于用户一次输入的数据量一般情况下较小(不会超过几百条记录),所以临时表可以建立在内存中,这样处理速度较快。  方法1

1221

用Delphi 开发数据库程序经验三则 (转)

用Delphi 开发数据库程序经验三则 (转)[@more@]1.建立临时表  数据输入是开发数据库程序的必然环节。在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,这就需要在本地(客户...

csd3176的博客 114

firebird database (快速入门) 简体版

firebird database (快速入门) 参考文件(均可自firebird网站找到):Novice's GuideMigration from MS-SQL to firebirdFirebord Release Notes 学习资料库基础是在sql的语法应用(请参考:firebird网站的说明文件最好把这份文件印出来,在写程式时可以参考其语,...

X660077的博客 1168

Database Comparer VCL for Delphi crack

支持的数据库列表不断更新,包括InterBase、FireBird、MySQL、MSSQL、Oracle、Sybase、PostgreSQL、DB2、PervasiveSQL、MSAccess、Paradox、DBASE以及其他可以通过OLEDB提供程序访问的数据库。同步Firebird、Interbase、MS SQL、Oracle、MySQL、Sybase、Postgre SQL等可能流行的数据库。根据数据库类型,比较表、约束、索引、触发器、生成器、存储过程、UDF、授予、角色和许多其他数据库对象。

q2315702359的博客 324
上一篇: [UDF系列]如何创建InterBase UDF
下一篇: [UDF系列]如何编写InterBase UDF 之三
warton
博客等级 码龄25年 61粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值