Delphi中FDQuery循环插入MySQL报错及try-finally异常疑问
一、为什么插入查询持续报错?
从你的代码和描述来看,插入操作失败大概率是以下几个原因导致的,我们逐个分析:
参数类型与数据库字段不匹配
你现在硬编码了参数值为'1'(字符串类型),但看注释里的原始值:frame_data_id对应数据库字段应该是整数类型(来自form2.FDQuery4.FieldByName('tfdid').AsString,但原字段很可能是整数),act_date是日期类型(来自tmSentTimeStamp.ToString)。如果数据库里的frame_data_id是INT、act_date是DATETIME类型,你传字符串'1'就会触发类型转换错误。
正确的做法是保持参数类型和字段一致:比如整数类型直接传数值,日期类型传TDateTime对象而不是字符串。FDQuery5未正确关联数据库连接
检查form2.FDQuery5的Connection属性是否已经绑定到目标数据库的FDConnection组件。如果连接未设置,执行SQL时会因为无法访问数据库而报错。SQL语句或参数名潜在错误
虽然你的SQL语句看起来语法没问题,但要确认:- 目标表
tm_frame_data_val确实存在,且字段名frame_data_id、value、act_date完全匹配(注意大小写,部分数据库区分大小写); - 参数名
fdida、value、acdoo和SQL里的占位符完全对应,没有拼写错误。
- 目标表
未显式Prepare查询(可选但推荐)
在循环里重复设置SQL文本时,显式调用form2.FDQuery5.Prepare可以避免重复解析SQL,也能提前发现语法或参数错误。比如在设置SQL.Text之后加上:form2.FDQuery5.Prepare;
二、为什么用了try-finally还会弹出错误提示框?
这是因为try-finally的作用是保证finally块的代码一定会执行,而不是捕获异常。你的代码里没有捕获异常的逻辑,当Execute抛出错误时,异常会向上传递到系统默认的异常处理机制,所以还是会弹出错误提示框。
另外,你的finally块现在不管有没有错误都会添加error on writing to db,这会导致即使插入成功也会记录错误,明显不符合预期——只有在异常发生时才应该记录错误。
如果想捕获异常并处理(比如只在列表里记录错误,不弹出提示),需要把try-finally改成try-except(或try-except-finally):
form2.FDQuery4.First; while (not form2.FDQuery4.Eof) do begin try form2.FDQuery5.SQL.Text := 'INSERT INTO `tm_frame_data_val` (`frame_data_id`, `value`, `act_date`) VALUES ( :fdida, :value, :acdoo );'; form2.FDQuery5.Command.CommandKind := skInsert; // 用匹配字段类型的参数赋值方式 form2.FDQuery5.ParamByName('fdida').AsInteger := form2.FDQuery4.FieldByName('tfdid').AsInteger; form2.FDQuery5.ParamByName('value').Value := // 这里根据字段类型用AsInteger/AsFloat等 form2.FDQuery5.ParamByName('acdoo').AsDateTime := tmSentTimeStamp; // 直接传日期对象,无需转字符串 form2.FDQuery5.Execute; except on E: Exception do begin form2.ListBox3.Items.Add( 'Error on writing to db: ' + E.Message ); // 如果不想让错误继续向上抛出,在这里处理后即可 end; end; form2.FDQuery4.Next; end;
内容的提问来源于stack exchange,提问作者roozgar

