Delphi FireDac 后续参数化 MySQL StoredProcedure 执行失败并出现 "Lost connection to MySQL server during query" 异常
Delphi FireDac subsequent parameterized MySQL StoredProcedure execution fails with "Lost connection to MySQL server during query" exception
为了重现问题,让我们有以下两个超级简单的 SP,第一个没有任何参数,第二个只有一个输出参数:
1. testsp_0_nopar:
CREATE DEFINER=`root`@`%` PROCEDURE `testsp_0_nopar`()
BEGIN
#do nothing
END
2. testsp_1_outpar:
CREATE DEFINER=`root`@`%` PROCEDURE `testsp_1_outpar`(OUT result INT)
BEGIN
SET result=100;
END
如果我们调用第一个 SP 两次,一个接一个,那么它可以正常工作:
var
sp: TFDStoredProc;
begin
try
con.ResourceOptions.AutoReconnect := false; // <- this is important in our project
con.Connected := True;
sp := TFDStoredProc.Create(nil);
try
sp.Connection := con;
sp.StoredProcName := 'mydatabase.testsp_0_nopar';
sp.ExecProc;
sp.Close;
sp.ExecProc;
finally
sp.Free;
end;
except
on e: exception do
begin
ShowMessage(e.Message);
end;
end;
但是如果我们调用第二个 SP 两次,一次又一次,那么我们会得到一个异常:
var
sp: TFDStoredProc;
begin
try
con.ResourceOptions.AutoReconnect := false; // this is important in our project
con.Connected := True;
sp := TFDStoredProc.Create(nil);
try
sp.Connection := con;
sp.StoredProcName := 'mydatabase.testsp_1_outpar';
sp.Params.Add('result', ftInteger, 1, ptOutput);
sp.ExecProc;
sp.Close;
sp.ExecProc; // <- this second sp call raises an exception
finally
sp.Free;
end;
except
on e: exception do
begin
ShowMessage(e.Message); // <- Lost connection to MySQL server during query
end;
end;
在现实生活中,我们必须在项目中使用不同的参数值频繁调用同一个 SP,因此每次都先释放然后重新创建 SP 对象并不是一个好的解决方案。
这在使用 AnyDac 的旧 Delphi 版本中运行良好,但在使用 FireDac 时我们遇到了这个问题。
非常感谢您的帮助! :)
看起来有人也 运行 解决了这个问题,并将解决方案发布到 Embarcadero 的质量中心:
https://quality.embarcadero.com/browse/RSP-31692
所以这是一个 FireDac 错误,要修复它,您必须按照上述 link 指示的方式编辑 FireDac 的源代码。我可以确认它解决了问题。
为了重现问题,让我们有以下两个超级简单的 SP,第一个没有任何参数,第二个只有一个输出参数:
1. testsp_0_nopar:
CREATE DEFINER=`root`@`%` PROCEDURE `testsp_0_nopar`()
BEGIN
#do nothing
END
2. testsp_1_outpar:
CREATE DEFINER=`root`@`%` PROCEDURE `testsp_1_outpar`(OUT result INT)
BEGIN
SET result=100;
END
如果我们调用第一个 SP 两次,一个接一个,那么它可以正常工作:
var
sp: TFDStoredProc;
begin
try
con.ResourceOptions.AutoReconnect := false; // <- this is important in our project
con.Connected := True;
sp := TFDStoredProc.Create(nil);
try
sp.Connection := con;
sp.StoredProcName := 'mydatabase.testsp_0_nopar';
sp.ExecProc;
sp.Close;
sp.ExecProc;
finally
sp.Free;
end;
except
on e: exception do
begin
ShowMessage(e.Message);
end;
end;
但是如果我们调用第二个 SP 两次,一次又一次,那么我们会得到一个异常:
var
sp: TFDStoredProc;
begin
try
con.ResourceOptions.AutoReconnect := false; // this is important in our project
con.Connected := True;
sp := TFDStoredProc.Create(nil);
try
sp.Connection := con;
sp.StoredProcName := 'mydatabase.testsp_1_outpar';
sp.Params.Add('result', ftInteger, 1, ptOutput);
sp.ExecProc;
sp.Close;
sp.ExecProc; // <- this second sp call raises an exception
finally
sp.Free;
end;
except
on e: exception do
begin
ShowMessage(e.Message); // <- Lost connection to MySQL server during query
end;
end;
在现实生活中,我们必须在项目中使用不同的参数值频繁调用同一个 SP,因此每次都先释放然后重新创建 SP 对象并不是一个好的解决方案。
这在使用 AnyDac 的旧 Delphi 版本中运行良好,但在使用 FireDac 时我们遇到了这个问题。
非常感谢您的帮助! :)
看起来有人也 运行 解决了这个问题,并将解决方案发布到 Embarcadero 的质量中心: https://quality.embarcadero.com/browse/RSP-31692
所以这是一个 FireDac 错误,要修复它,您必须按照上述 link 指示的方式编辑 FireDac 的源代码。我可以确认它解决了问题。