如何在mORMot中调用Firebird存储过程?求指导及示例
刚好我之前在重构类似的Delphi+Firebird项目时用到过mORMot调用存储过程,完全不用硬把所有存储过程逻辑迁到应用层,给你分享几种实用的调用方式和代码示例,帮你快速搞定:
1. 直接调用无返回结果的存储过程(更新类操作)
如果你的存储过程是执行数据更新、删除这类没有结果集的操作,直接用mORMot的TSQLDBFirebirdConnection执行SQL语句就行,非常简单:
procedure CallUpdateStoredProc; var DBConn: TSQLDBFirebirdConnection; begin // 初始化Firebird连接,参数分别是数据库路径、用户名、密码 DBConn := TSQLDBFirebirdConnection.Create('localhost:C:\YourAppDB.fdb', 'sysdba', 'masterkey'); try // 调用无参数的存储过程 DBConn.Execute('EXECUTE PROCEDURE RefreshUserCache;'); // 调用带输入参数的存储过程(比如更新指定用户的状态) DBConn.Execute('EXECUTE PROCEDURE UpdateUserStatus(?, ?)', [1001, 'ACTIVE']); finally DBConn.Free; end; end;
2. 调用返回单结果集的存储过程(查询类操作)
如果存储过程返回查询结果,用TSQLDBStatement和TSQLDBRows来读取结果集,比直接用ADO更贴合mORMot的生态:
procedure CallQueryStoredProc(UserID: Integer); var DBConn: TSQLDBFirebirdConnection; Stmt: TSQLDBStatement; Rows: TSQLDBRows; begin DBConn := TSQLDBFirebirdConnection.Create('localhost:C:\YourAppDB.fdb', 'sysdba', 'masterkey'); try // 预编译存储过程调用语句(支持参数绑定) Stmt := DBConn.Prepare('EXECUTE PROCEDURE GetUserOrders(?)'); try // 绑定输入参数(第一个参数对应UserID) Stmt.Bind(1, UserID); // 执行并获取结果集 Rows := Stmt.ExecuteFetch; try // 遍历结果集读取数据 while Rows.Step do begin ShowMessage(Format('订单ID: %d | 金额: %.2f | 创建时间: %s', [ Rows.FieldInt('ORDER_ID'), Rows.FieldDouble('ORDER_AMOUNT'), DateTimeToStr(Rows.FieldDateTime('CREATE_TIME')) ])); end; finally Rows.Free; end; finally Stmt.Free; end; finally DBConn.Free; end; end;
3. 调用带输出参数的存储过程
如果你的存储过程有输出参数,Firebird需要用命名参数绑定,mORMot也支持这种场景:
procedure CallSPWithOutputParams(UserID: Integer; out TotalAmount: Double); var DBConn: TSQLDBFirebirdConnection; Stmt: TSQLDBStatement; begin TotalAmount := 0; DBConn := TSQLDBFirebirdConnection.Create('localhost:C:\YourAppDB.fdb', 'sysdba', 'masterkey'); try // Firebird中带输出参数的存储过程调用语法,用:参数名标记输出参数 Stmt := DBConn.Prepare('EXECUTE PROCEDURE CalculateUserTotal(?, :OUT_TOTAL)'); try // 绑定输入参数 Stmt.Bind(1, UserID); // 绑定输出参数,指定参数类型 Stmt.BindOutput('OUT_TOTAL', OUTPUT_PARAMETER_DOUBLE); // 执行存储过程 Stmt.Execute; // 读取输出参数值 TotalAmount := Stmt.FieldDouble('OUT_TOTAL'); finally Stmt.Free; end; finally DBConn.Free; end; end;
4. 通过mORMot REST服务封装存储过程(客户端-服务器架构)
如果你的应用是客户端-服务器模式,建议把存储过程调用封装到mORMot的服务端方法中,客户端通过REST接口调用,这样更符合mORMot的架构设计:
服务端代码(定义服务方法)
type // 自定义服务类,继承自TSQLRestServer TAppServerMethods = class(TSQLRestServer) public // 暴露给客户端的方法:获取指定用户的订单 function GetUserOrders(UserID: Integer): TSQLRecordArray; end; function TAppServerMethods.GetUserOrders(UserID: Integer): TSQLRecordArray; var DBConn: TSQLDBFirebirdConnection; Stmt: TSQLDBStatement; Rows: TSQLDBRows; OrderRec: TSQLOrder; // 假设你已经定义了对应订单的TSQLRecord子类 begin Result := nil; // 从Model中获取预配置的Firebird连接字符串(推荐用这种方式,避免硬编码) DBConn := TSQLDBFirebirdConnection.Create(Model.ConnectionProperties, 'sysdba', 'masterkey'); try Stmt := DBConn.Prepare('EXECUTE PROCEDURE GetUserOrders(?)'); try Stmt.Bind(1, UserID); Rows := Stmt.ExecuteFetch; try while Rows.Step do begin OrderRec := TSQLOrder.Create; OrderRec.ID := Rows.FieldInt('ORDER_ID'); OrderRec.Amount := Rows.FieldDouble('ORDER_AMOUNT'); OrderRec.CreateTime := Rows.FieldDateTime('CREATE_TIME'); // 将记录添加到结果数组 Add(Result, OrderRec); end; finally Rows.Free; end; finally Stmt.Free; end; finally DBConn.Free; end; end;
客户端代码(调用REST服务)
procedure ClientGetUserOrders(UserID: Integer); var Client: TSQLRestClientURI; Orders: TSQLRecordArray; i: Integer; begin // 初始化REST客户端,指定服务端地址和数据模型 Client := TSQLRestClientURI.Create('http://your-server:8080', TSQLModel.Create([TSQLOrder]), 'app-user', 'app-pass'); try // 调用服务端的GetUserOrders方法 Orders := Client.CallBackGet<TSQLOrder>('GetUserOrders', [UserID]); try // 处理返回的订单数据 for i := 0 to High(Orders) do begin ShowMessage(Format('订单 %d: %.2f', [Orders[i].ID, Orders[i].Amount])); end; finally // 释放结果数组 TSQLRecord.FreeArray(Orders); end; finally Client.Free; end; end;
一些实用建议
- 复用数据库连接:尽量用mORMot的
TSQLDBConnectionPool来管理连接池,避免频繁创建销毁连接,提升性能 - 逐步重构:先把存储过程封装到mORMot服务中,保证业务正常运行,后续再逐步把一些简单的存储过程逻辑迁移到应用层
- 版本兼容:确保mORMot的Firebird驱动版本和你的Firebird服务器版本匹配(mORMot支持Firebird 2.5及以上版本)
内容的提问来源于stack exchange,提问作者Pluem Saan
相关产品推荐
相关产品推荐

