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

如何通过TADOStoredProc获取存储过程的RAISERROR进度消息?

可以通过TADO组件实时获取RAISERROR WITH NOWAIT的进度消息

结论是可以实现,但需要正确配置ADO组件并处理对应的事件,以下是具体实现步骤:

1. 配置ADO组件属性

  • 将TADOStoredProc关联的TADOConnection的CursorLocation设置为clUseServer:客户端游标会缓存结果集和消息,无法实时获取进度;服务器端游标才能让SQL Server实时推送消息。
  • 给TADOStoredProc的ExecuteOptions添加eoAsyncExecute:适配你的线程异步执行场景,同时确保消息能被实时捕获。

2. 处理ADOConnection的OnInfoMessage事件

SQL Server通过RAISERROR WITH NOWAIT发送的信息类消息(严重级别1-10)会触发TADOConnection的OnInfoMessage事件,你可以在这个事件中获取进度消息并更新UI:

procedure TMainForm.ADOConnInfoMessage(Connection: TADOConnection;
  const Error: Error; var EventStatus: TEventStatus);
begin
  // 跨线程更新UI必须同步到主线程
  TThread.Synchronize(nil, procedure
  begin
    ProgressMemo.Lines.Add('进度:' + Error.Description);
  end);
end;

3. 存储过程的要求

  • RAISERROR的严重级别必须在1-10之间:级别≥11会被ADO判定为错误,触发OnError事件而非OnInfoMessage。
  • 必须带WITH NOWAIT关键字:否则SQL Server会把消息缓存到存储过程执行结束后才一次性发送,无法实时展示进度。

示例存储过程代码:

CREATE PROCEDURE dbo.LongRunningProcess
AS
BEGIN
  SET NOCOUNT ON;

  RAISERROR('正在初始化数据...', 0, 1) WITH NOWAIT;
  WAITFOR DELAY '00:00:03'; -- 模拟耗时操作

  RAISERROR('已完成30%,正在处理核心逻辑...', 0, 1) WITH NOWAIT;
  WAITFOR DELAY '00:00:05';

  RAISERROR('处理完成,正在生成结果...', 0, 1) WITH NOWAIT;
  WAITFOR DELAY '00:00:02';

  RAISERROR('全部执行完成!', 0, 1) WITH NOWAIT;
END

4. 线程执行的注意事项

  • 线程中操作ADO组件时,建议为每个线程创建独立的TADOConnection实例,避免多线程共享连接导致的线程安全问题。
  • 调用TADOStoredProc.Execute时,确保异步选项已开启,线程不会阻塞主线程,同时保证消息能被实时捕获。

内容的提问来源于stack exchange,提问作者Keith Miller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:00:17