繁体   English   中英

Delphi/FireDac + PostgreSQL + stored procedure + Procedure(要调用一个过程,使用CALL)

[英]Delphi/FireDac + PostgreSQL + stored procedure + Procedure (To call a procedure, use CALL)

我们正在为我们的系统提供 postgreSQL 数据库支持,我们目前使用 Oracle。

我们正在尝试调用数据库中的过程,就像我们在 Oracle 中调用的那样。

var conBanco := TFDConnection.Create(Self);
try
   conBanco.Params.Database := 'Database';
   conBanco.Params.UserName := 'UserName';
   conBanco.Params.Password := 'Password';
   conBanco.Params.Values['Server'] := 'IP';
   conBanco.Params.DriverID := 'PG';
   conBanco.Open();

   var stpBanco := TFDStoredProc.Create(Self);
   try
      stpBanco.Connection := conBanco;
      stpBanco.StoredProcName := 'gerador_padrao';
      stpBanco.Prepare;
      stpBanco.ParamByName('gerador').Value := 'pessoas';
      stpBanco.ExecProc();
      ShowMessage(VarToStrDef(stpBanco.ParamByName('parchave').Value, ''));
   finally
      stpBanco.Free;
   end;
finally
   conBanco.Free;
end;

但是我们收到以下错误:

异常 class:异常

异常消息:EPgNativeException:[FireDAC][Phys][PG][libpq] 错误:superus.gerador_padrao(gerador => character varying, parchave => numeric) is a procedure。 要调用过程,请使用 CALL。

数据库中的存储过程:

CREATE OR REPLACE PROCEDURE superus.gerador_padrao
     (gerador character varying, INOUT parchave numeric)
LANGUAGE plpgsql
AS $procedure$
begin
   --Code
end;
$procedure$
;

错误发生在以下行:

stpBanco.Prepare;

上面的代码在Oracle中完美运行,那么在PostgreSQL中如何调用程序呢?

谢谢你。

下面说说Delphi 10.2.3,可能以后的版本不一样了。

在文件 FireDAC.Phys.PGMeta.pas 中有一个 TFDPhysPgCommandGenerator.GetStoredProcCall 方法,其中形成了过程文本,没有通过 CALL 调用过程的选项。 此外,整个文件中没有“CALL”文本。 也许这是一个错误,或者也许是某种狡猾的想法……但这并没有让我们变得更容易。

  // function returns void
  if not lHasOut then begin
    if FCommandKind = skStoredProc then
      FCommandKind := skStoredProcNoCrs;
    // NULL to avoid problem with execution of a
    // void function in binary result format
    Result := 'SELECT NULL FROM ';
  end
  else begin
    if lHasCrs and (FCommandKind = skStoredProc) then
      FCommandKind := skStoredProcWithCrs
    else if lFunc then
      lFunc := FCommandKind in [skStoredProc, skStoredProcNoCrs];
    if lFunc then
      Result := 'SELECT '
    else
      Result := 'SELECT * FROM ';
  end;

总的来说,我在这里看到 2 个选项:

  1. 自己形成过程调用字符串。 我相信这并不困难,当然,当组件执行它时它更正确。
  2. 代替过程,制作具有相同内容的 function,并将您的 output 参数作为结果。 重要的是要记住——在这种情况下过程调用必须通过 ExecFunc;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM