Delphi中TWebModule接口出现Access Violation错误求助
问题排查与修复
核心原因
变量a: TJSONArray仅声明但未初始化创建实例,当带CF参数查询返回结果(RecordCount>0)时,执行a.AddElement(o)会访问空指针,触发访问违规错误。全量查询时可能未进入RecordCount>0的分支,因此未触发错误。
修复步骤
- 初始化JSON数组:在使用
a前创建实例,避免空指针访问 - 遍历所有查询结果:原代码仅处理第一条记录,需改成循环遍历所有行
- 内存泄漏防护:使用
try/finally确保JSON对象和数组被正确释放 - 无结果处理:查询无数据时返回空JSON数组,避免响应内容异常
修复后的完整代码示例
procedure TWebModule2.ClientGetItem(Request: TWebRequest; Response: TWebResponse); var o: TJSONObject; CfKey: string; a: TJSONArray; begin CfKey := Request.QueryFields.Values['CF']; // 构建SQL语句 if Request.QueryFields.Count > 0 then begin QryClientParam.SQL.Text := 'select * from TABLE where COD_FISC = :CF'; QryClientParam.Params.ParamByName('CF').AsString := CfKey; end else begin QryClientParam.SQL.Text := 'select * from TABLE'; end; QryClientParam.Active := true; Response.ContentType := 'application/json'; try if QryClientParam.Active and (QryClientParam.RecordCount > 0) then begin a := TJSONArray.Create; try QryClientParam.First; // 循环遍历所有记录 while not QryClientParam.Eof do begin o := TJSONObject.Create; try o.AddPair('Descrizione', QryClientParam.FieldByName('DESK').AsString); o.AddPair('Codice Fiscale', QryClientParam.FieldByName('COD_FISC').AsString); o.AddPair('CAP', QryClientParam.FieldByName('CAP01').AsString); o.AddPair('Indirizzo', QryClientParam.FieldByName('INDIRI').AsString); o.AddPair('Citta', QryClientParam.FieldByName('CITTA01').AsString); a.AddElement(o); // 数组接管对象生命周期,无需手动释放o except o.Free; // 异常时手动释放未加入数组的对象 raise; end; QryClientParam.Next; end; Response.Content := a.ToString; finally a.Free; // 释放数组 end; end else begin Response.Content := '[]'; // 无数据返回空数组 end; finally QryClientParam.Active := false; // 关闭数据集 end; end;
额外注意事项
- 确保
QryClientParam是线程安全的:Web请求是并发处理的,建议使用局部查询组件而非全局组件,避免并发冲突 - 核对字段名:代码中
INDIRI等字段名需与数据库实际字段完全一致,避免字段不存在引发的错误
内容的提问来源于stack exchange,提问作者Nu Carvignulu
相关产品推荐
相关产品推荐

