You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:27:47