【发布时间】:2018-07-14 13:30:18
【问题描述】:
我最近开始在 Delphi XE5 中使用 FDConnection 组件的 [ExecSQLScalar]1 和 [ExecSQL]2 方法。不需要构建一个 Dataset 对象非常方便,比如 FDQuery 只用于简单的查询或执行。
但是,在执行一个带有 void return 的函数时,我遇到了一个奇怪的问题,该函数具有可以生成异常的内部验证。我正在使用 Postgres 数据库。
CREATE FUNCTION can_be_exception()
RETURNS void AS
$$
BEGIN
RAISE EXCEPTION E'fail';
END;
$$
LANGUAGE plpgsql STABLE;
在delphi中,我调用ExecSQLScalar函数...
FDConnection1.ExecSQLScalar('select 1');
FDConnection1.ExecSQLScalar('select can_be_exception()');
在第一次运行时,我收到以下错误:
项目 TFDConnectionDEMO.exe 引发异常类 带有消息“[FireDAC][Phys][PG][libpq] 错误的 EPgNativeException: 失败”。
在第二次运行时,我收到了违规访问错误:
项目 TFDConnectionDEMO.exe 引发异常类 $C0000005 消息“0x00000000 处的访问冲突:读取地址 0x00000000”。
显然错误发生在单元FireDAC.Comp.Client下面的行中
function TFDCustomConnection.ExecSQLScalar(const ASQL: String;
const AParams: array of Variant; const ATypes: array of TFieldType): Variant;
var
oCmd: IFDPhysCommand;
begin
oCmd := BaseCreateSQL;
try
if BasePrepareSQL(oCmd, ASQL, AParams, ATypes) or (FExecSQLTab = nil) then begin
FDFree(FExecSQLTab);
...
忽略之前的错误并重试,显示另一个错误...
Project TZConnectionDEMO.exe 引发异常类 EFDException 消息'[FireDAC][DatS]-24。行没有嵌套'。
搜索,我没有找到对此错误的响应。我认为我的错误是使用 FDConnection 组件的 ExecSQLScalar 函数调用银行 raise_exception 函数。所以我尝试使用FDConnection.ExecSQL,正如我想象的那样,如果参数中有SELECT 子句,则不能使用它。
有没有更好的方法来使用 FDConnection.ExecSQL 调用具有 void 返回的函数? BUG 会在组件中吗?还是打这种电话不正确?
【问题讨论】:
-
我无法在东京使用 PostgreSQL 10.1 重现这一点。但我想我知道为什么。在
FDFree(FExecSQLTab)之后似乎还有一个悬空指针。在东京有FDFreeAndNil(FExecSQLTab)。 -
太棒了!我制作了该文件的副本并按照您所说的进行了更改......它按预期工作。非常感谢你。显然,在以前版本的 IDE 中制作的应用程序的稳定性并不让 embarcadero 感兴趣
-
不客气! EBMT 的典型做法是不关心修复传播到旧版本。
-
@Victoria:不错的收获!为什么不将其发布为答案?
-
@Victoria:很高兴你有时间去做。 +1
标签: database postgresql delphi firedac