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

ZEOSLib中TZReadOnlyQuery调用MariaDB存储过程报错求助

问题分析与解决

核心原因

TZReadOnlyQuery是ZeosLib专为只读单结果集查询设计的组件,不支持以下场景:

  1. 一次执行多语句(你用的SET + CALL + SELECT是三个独立SQL语句)
  2. 处理存储过程的INOUT/OUT参数交互
  3. 多结果集的切换与读取

这类组件内部逻辑会强制校验语句类型,对非SELECT类语句(如SET、CALL)的兼容性极差,自然会抛出异常。

解决办法

方法一:改用TZQuery并启用多语句支持

TZQuery比TZReadOnlyQuery更灵活,支持多语句执行与多结果集处理:

  1. 将组件替换为TZQuery
  2. 把数据库连接组件的MultiStatements属性设为True(允许一次执行多个SQL语句)
  3. 用ExecSQL执行复合语句,再切换结果集获取数据:
ZQuery1.SQL.Text := 'set @x = ''inputparam''; call MyProc(@x, @y); select @x, @y;';
ZQuery1.ExecSQL;
// 跳过SET、CALL的无结果阶段,切换到SELECT的结果集
ZQuery1.NextResult; 
while not ZQuery1.Eof do
begin
  ShowMessage('@x=' + ZQuery1.FieldByName('@x').AsString + ', @y=' + ZQuery1.FieldByName('@y').AsString);
  ZQuery1.Next;
end;

方法二:参数绑定调用存储过程(推荐)

这是符合Zeos设计规范的写法,更安全且易维护:
直接通过组件参数绑定处理INOUT/OUT参数,无需会话变量:

ZQuery1.SQL.Text := 'CALL MyProc(:a, :r);';
// 配置INOUT参数
ZQuery1.ParamByName('a').ParamType := ptInputOutput;
ZQuery1.ParamByName('a').AsString := 'inputparam';
// 配置OUT参数
ZQuery1.ParamByName('r').ParamType := ptOutput;
ZQuery1.ParamByName('r').DataType := ftString;
ZQuery1.ParamByName('r').Size := 255;

// 执行存储过程
ZQuery1.ExecSQL;

// 读取返回值
ShowMessage('INOUT参数返回值: ' + ZQuery1.ParamByName('a').AsString);
ShowMessage('OUT参数返回值: ' + ZQuery1.ParamByName('r').AsString);

内容的提问来源于stack exchange,提问作者Heinzi Tuberkel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:06:05